【问题标题】:clearTimeout on Mouseover Event not clearing setTimeout from Mouseout Event鼠标悬停事件上的 clearTimeout 未从 Mouseout 事件中清除 setTimeout
【发布时间】:2011-03-27 14:19:56
【问题描述】:

我有一些代码可以将鼠标悬停事件和鼠标悬停事件添加到页面上的所有“a”标签。我希望鼠标悬停启动一个 5 秒的计时器,之后它会调用一个函数。但是,如果触发了新的 mouseover 事件,它应该取消任何现有的计时器。我正在使用的代码如下。 setTimeout() 工作正常,但似乎 clearTimeout() 没有引用正确的 timeoutID,即使我在全局范围内声明了它。有什么建议吗?

var timeoutID;

function addMouseoverEvent() {
    $('a').each(function(index) {
        $(this).mouseover(function() {
            clearTimeout(timeoutID);
            // do stuff
        })
    }); 
}

function addMouseoutEvent() {
    $('a').each(function(index) {
        $(this).mouseout(function() {
            timeoutID = setTimeout(function() {
                // do stuff
            }, 5000);
        })
    });
}

$(window).load(function() {
    addMouseoverEvent();
    addMouseoutEvent();
});

我应该澄清一下,实际上应该只有一个活动计时器。这就是为什么我希望它是全球性的。如果发生鼠标悬停事件,则不应保留任何计时器。如果发生 mouseout 事件,则只有一个计时器应该处于活动状态 - 由最后一个 mouseout 事件触发的计时器。

【问题讨论】:

  • 你的锚里面有图片吗?还是其他元素?
  • 是的,可能有图像。不知道元素是什么(这实际上是一个 Chrome 插件,它将在访问的每个页面上运行,因此页面的内容可以是任何内容)。

标签: javascript jquery events timeout


【解决方案1】:

我知道它已经得到了回答,但我发现只需删除 .each() 调用就可以按预期工作。在this Fiddle 上尝试小悬停游戏。

(function game () {
    var timeoutID;
    $('a').mouseover(function() {
        $('#box').html('All is well.').removeClass('bang');
        clearTimeout(timeoutID);
        // do stuff
    });
    $('a').mouseout(function() {
        $('#box').html('You have 2 seconds to return!');
        timeoutID = setTimeout(function() {
            $('#box').addClass('bang').html('Too Late!');
            // do stuff
        }, 2000);
    });
}());

我很可能遗漏了一些东西——但悬停游戏似乎运行良好。

【讨论】:

  • 在 jsFiddle 上进行了测试,你是对的,它确实在那里工作。我 90% 的肯定它昨晚在我的实施中没有起作用,但是已经很晚了,我很累。 +1 只是为了花时间测试它,因为它看起来确实有效(至少在小提琴沙箱中)。
【解决方案2】:

如果您的 timeoutId 是 globall,那么它会在 $('a').each() 的每次迭代中被覆盖。如果您使用的是 1.4,则最有可能使用 delay 方法。或者您可以使用 $(this).data('timeoutId', setTimeout(youFunction)` 将 timeoutId 存储在元素上。

【讨论】:

  • 虽然他没有在.each() 中分配它,但它发生在处理程序中......实际上.each() 是无关的,他可以完全删除该闭包。
  • 但是它仍然在迭代,因为在重新调整的集合中有不止一个 a 元素......虽然使用 each 是多余的。
  • 我已根据您的建议删除了 .each() 。更好的代码,但 clearTimeout() 仍然不起作用。如果我将 timeoutID 存储在每个元素上,在调用 clearTimeout() 时是否需要遍历每个元素的 timeoutID 以确保我得到了所有元素?
  • .data() 方法成功了,尽管我将它绑定到 $(document) 以便它具有全局范围。在mouseover 事件中调用setTimeout() 之前还必须调用clearTimeout($(document).data('timeoutID'))。谢谢!
  • @dosboy - 问题是元素 inside 锚点,因为 mouseout离开孩子 时也会触发,您可能会得到使用您的原件,只需使用 mouseentermouseleave 而不是 mouseovermouseout :)
猜你喜欢
  • 1970-01-01
  • 2018-08-13
  • 1970-01-01
  • 2023-03-14
  • 1970-01-01
  • 2012-10-12
  • 1970-01-01
  • 2020-06-25
  • 2011-11-09
相关资源
最近更新 更多