【问题标题】:Clearing timeouts with javascript使用 javascript 清除超时
【发布时间】:2012-12-29 02:39:19
【问题描述】:

我遇到了某种变量超出范围的问题或其他问题。在下面的函数中,我根据鼠标是进入还是退出来创建或清除超时。不过,似乎即使创建了超时,它在重新进入时也会返回 undefined 。不知道我在这里做错了什么,感谢您的帮助!

jsFiddle example

JavaScript:(具体问题在 else 第 35 行有条件

var navLinks = $('nav li.sub');

navLinks.mouseenter(function(){

  console.log('hovering on link');

  var thiis   = $(this),
      subList = thiis.find('ul'),
      autoClose;

  if (!thiis.hasClass('out')){

    console.log('isnt out');

    /* Link */

    thiis

    /* Show submenu when entering link */

    .addClass('out')

    /* Hide submenu when exiting link */

    .mouseleave(function(){

      autoClose = setTimeout(function(){

        thiis.removeClass('out');
      }, 1000);


      console.log('exiting link: timeout active', autoClose);
    });
  } else {

    console.log ('is out', autoClose);

    if (autoClose){

      console.log('is out: clear timeout');

      clearTimeout(autoClose);
    }
  }
});

【问题讨论】:

  • 如所写,var autoClose 确保autoClosemouseenter 处理程序的本地,每次触发时。如果您想从先前的mouseenter 事件中获得clearTimeout(autoClose),那么您必须将var autoClose 放在外部范围内。因此,相同的autoClose 将可用于事件处理程序的每个执行上下文,并且可以根据需要设置/清除。
  • 尝试像navLinks.each(function () { var autoClose; $(this).mouseenter(/**/); });一样包装它
  • @Beetroot-Beetroot 知道了 - 让它成为答案,我愿意接受它
  • @metadings 很棒的提示,谢谢

标签: javascript jquery hover timeout


【解决方案1】:

技术,

简单的答案就是将var autoClose 移至外部范围,但我认为您可以(并且应该)做更多。

更具体地说,

  • 我认为您不想在mouseenter 处理程序中附加mouseleave 处理程序。它可以从一开始就永久连接。
  • mouseenter处理程序中,clearTimeout(autoClose)thiis.addClass('out')可以无条件执行。测试.hasclass('out')没有真正的经济。

试试这个:

var navLinks = $('nav li.sub');
var autoClose;
navLinks.hover(function(){
    var thiis = $(this);
    clearTimeout(autoClose);
    thiis.addClass('out');
}, function(){
    var thiis = $(this);
    autoClose = setTimeout(function(){
        thiis.removeClass('out');
    }, 1000);
});

【讨论】:

  • 值得一提的是在超时时间内$(this)指的是窗口,所以最好设置一个类似于mouseenter实现的navLink的变量。此外,对于速记,现在可以使用 .hover() 方法作为两者的速记:.hover(function(){}, function(){});
【解决方案2】:

您应该使用全局对象来存储一些变量,例如超时和间隔的引用。 例如,您可以声明这样一个对象:

// Declare the context object in the global scope
var myContext = {
    "myTimeout" : false
}

然后在 mouseenter 和 mouseleave 处理函数中使用上下文对象。

【讨论】:

    【解决方案3】:

    正如 cmets 中指出的那样,每次鼠标悬停一个项目时,您都会有新的超时。让我们为每个项目创建新的超时变量:

    $('nav li:has(ul)').each(function(){
      var par = $(this),
          sub = $("> ul", this),
          closeTO;
    
      par.hover(
        function(){
          clearTimeout(closeTO);
          par.addClass("out");
        },
        function(){
          closeTO = setTimeout(function(){
            par.removeClass("out");        
          }, 1000);
        }
      );
    });
    

    http://jsfiddle.net/ByuG3/1/

    【讨论】:

      猜你喜欢
      • 2012-02-10
      • 1970-01-01
      • 2013-10-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-08-28
      • 2015-07-04
      • 1970-01-01
      相关资源
      最近更新 更多