【问题标题】:Simulate clearTimeout() action within a setTimeout() function在 setTimeout() 函数中模拟 clearTimeout() 动作
【发布时间】:2012-06-08 13:14:23
【问题描述】:

通常 setTimeout() 方法的执行被 setTimeout() 方法之外的 clearTimeout() 方法中止,但在我的情况下,我需要在循环本身中中止 setTimeout() 循环的执行如果某个事件在指定的“等待期”内发生。

在下面显示的代码中,用户有 500 毫秒的时间来激活代码 A。如果他未能在时间范围内激活代码 A,代码 B 将作为后备执行。在代码 A 中,我标记了两个地方:1)停止超时的地方和 2)我希望退出函数的地方。

我的jsFiddle is here

我的 JavaScript 和 HTML 代码的副本如下所示:

HTML

<table id="headMenu">
    <tr>
        <td id="head1">Item 1</td>
        <td id="head2">Item 2</td>
        <td id="head3">Item 3</td>
    </tr>
</table>
<table id="subMenu">
    <tr>
        <td>Dynamic Content!</td>
    </tr>
</table​​​​​​​​​​​​​​​​​​​​​​​​​​​​>​​​

JavaScript

a = 500;
document.getElementById("head1").onmouseover = function(displayMenu) {
    document.getElementById("subMenu").innerHTML = "<tr><td>Item A</td><td>Item B</td><td>Item C</td></tr>";
    document.getElementById("head1").onmouseout = function(getScroll) {
        setTimeout(function() {
            document.getElementById("subMenu").onmouseover = function(breakTimeout) { // **Code A**
                a = 10000;
                // **Stop timeout.**  Now never execute Code B.
                document.getElementById("subMenu").onmouseout = function(endFunction) {
                    document.getElementById("subMenu").innerHTML = '<tr><td>Content is Dynamic!</td></tr>';
                    // **Exit function here immediately**
                }
            }
            if(a==500){
            //**Code B**:  Only execute if **Code A** never executed within time frame
                document.getElementById("subMenu").innerHTML = '<tr><td>Dynamic Content!</td></tr>';
            }
        }, a)
    }
}​

我希望我的设计理念也很明显。如果我的代码和描述不够清楚,我很乐意澄清更多问题。

非常感谢任何可以得到答案的人并 +1!

【问题讨论】:

  • 你能解释一下——具体参考你页面上的 HTML 元素——你想要什么吗?
  • 当mouseover id="head1", getinnerHTML of id="submenu" 显示Item A Item B Item C 菜单。 Onmouseout of "head1",在 500 毫秒后隐藏子菜单,除非鼠标移到 id="submenu" 上(即滚动该菜单)。如果为 true,则在鼠标离开子菜单之前永远不要隐藏子菜单。如果为真,立即将 submenu.innerHTML 改回“动态内容”。

标签: javascript html function dhtml timing


【解决方案1】:

你原来的前提是有缺陷的。传递给setTimeout() 的函数体直到时间过去后才会执行,因此您想要停止超时的代码不会执行,直到为时已晚。我已修改您的代码以使用标准 clearTimeout(),它应该可以满足您的需求。

var a = 500, head1 = document.getElementById('head1'), subMenu = document.getElementById('subMenu'), timeout;

head1.onmouseover = function(displayMenu) {
    subMenu.innerHTML = '<tr><td>Item A</td><td>Item B</td><td>Item C</td></tr>';
    head1.onmouseout = function(getScroll) {
        subMenu.onmouseover = function(breakTimeout) {
            clearTimeout(timeout);
            subMenu.onmouseout = function(endFunction) {
                subMenu.innerHTML = '<tr><td>Content is Dynamic!</td></tr>';
            };
        };
        timeout = setTimeout(function() {
            document.getElementById("subMenu").innerHTML = '<tr><td>Dynamic Content!</td></tr>';
        }, a);
    };
};

Working DEMO

【讨论】:

  • 你知道为什么我不能在项目 A、项目 B 或项目 C 之间滚动吗?
  • @wagtail 对代码和 jsFiddle 进行了小幅编辑。我没有将a 传递给setTimeout() 调用,因此该函数只是自动执行。我还在小提琴中将延迟从半秒增加到了两秒,这样就更明显了。
  • 是的,时机非常好!这是很棒的代码,我只希望在它变为“内容是动态的!”之前我可以滚动浏览所有子菜单!
  • 我还是卡住了,我不明白为什么当我只留下 的一个
【解决方案2】:

可以使用全局变量来存储setTimeout()的返回值

window.myTimeout = setTimeout(function() {
    // ...
}, a);

然后您可以像这样从任何上下文中清除超时(只要 window.myTimeout 没有被修改):

clearTimeout(window.myTimeout);

注意:“窗口”部分是可选的。这只是我个人用来简化识别全局变量的约定,尤其是在代码复杂/庞大的情况下。

【讨论】:

  • 但这会清除整个循环,包括我仍想执行的部分(即代码A
  • @wagtail 你的整个前提是有缺陷的。直到 超时结束后,代码 A 才会执行。
  • 真的。我将如何重新安排这个?起初我没有看到这个!
  • @wagtail 现在正在处理这个问题 - 我直接想到了它,然后又失去了它。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-03-02
  • 2021-02-12
  • 1970-01-01
  • 2011-12-31
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多