【问题标题】:Mouseout event fires before mouse is actually out在鼠标实际退出之前触发 Mouseout 事件
【发布时间】:2011-11-07 14:21:50
【问题描述】:

我有一个 mouseover / mouseout 处理程序。两者都使用 Javascript 超时来延迟他们的工作。但是即使鼠标仍在选择器上方,mouseout 事件也会触发。在 mouseout 脚本中关闭超时时,它可以正常工作。所以我想我在超时方面做错了什么。有点像

      $('.selector').live( {mouseover : function() {
          var timeout = setTimeout(function() {
        $('.something' ).show();
          }, 1000);
    }, mouseout: function () {
          timeout = setTimeout(function() {
        $('.something' ).hide();    
          }, 2000);
    }
      });

如果我使用悬停处理程序而不是 mouseover / mouseout,也会发生同样的事情。如果我对两个超时使用不同的变量名,或者如果我在调用另一个超时之前清除一个超时,同样的事情。我做错了什么?

【问题讨论】:

  • 在FF中可以正常使用,你用的是哪个浏览器?

标签: javascript jquery events timeout mouseevent


【解决方案1】:

由于它可以正常工作而没有超时,我认为 mouseover/mouseout 对您来说是正确的事件,而不是 mouseenter/mouseleave。

您不断调用多个超时,这些超时在各处触发,您需要使用一个计时器,它一次只计时一件事:

(function () {
var timeout = 0;
    $('.selector').live({
    mouseover: function () {
    window.clearTimeout( timeout );
        timeout = setTimeout(function () {
        $('.something').show();
        }, 1000);
    },
    mouseout: function () {
    window.clearTimeout( timeout );
        timeout = setTimeout(function () {
        $('.something').hide();
        }, 2000);
    }
    });
})()

window.setTimeout 只返回一个普通整数。每次调用window.setTimeout 时,都会创建一个新计时器,无论返回值分配给哪个变量。 window.setTimeout的返回值可以用来清空特定的定时器。

作为副作用,您可以清除甚至不知道存在的超时。例如:

jQuery("div").fadeOut( 15000 );

var l = 10000;

while( l-- ) window.clearTimeout( l );

您正在暴力破解 10000 个不同的计时器 ID 并将它们全部清除,取出 jQuery fx 内部计时器来阻止淡出。请勿在实际代码中使用,仅用于演示目的。

【讨论】:

  • 你不应该蛮力超时。 Jquery 有一个 .stop() 方法用于这个确切的目的,具有更多的控制和可靠性。
  • @iliacholy,这不是重点,而是演示计时器的工作原理。运行代码根本不等同于 .stop(),它实际上破坏了 jQuery,因为 jQuery 内部不希望计时器从外部神奇地移除。
  • @Esailija 是的,只是想确保操作人员知道这一点。
  • 好的,那么通常更好的是:.stop(),还是从外部停止超时?我认为 .stop() 仅适用于由 jQuery 发起的动画。
  • @cincplug 不要从外部搞乱 jQuery 超时,jQuery 中有适当的方法来阻止它们。
【解决方案2】:

您应该清除超时,以免它们重叠。

var timeout = null;
$('#foo').live({
    mouseover: function() {
        if(timeout !== null){ 
            clearTimeout(timeout); 
            timeout = null;
        }
        timeout = setTimeout(function() {
            $('#bar').show();
        }, 1000);
    },
    mouseout: function() {
        if(timeout !== null){ 
            clearTimeout(timeout); 
            timeout = null;
        }
        timeout = setTimeout(function() {
            $('#bar').hide();
        }, 2000);
    }
});

演示:http://jsfiddle.net/46mFc/1/

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-08-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-11-02
    相关资源
    最近更新 更多