2012-04-18 41 views
0

我有一个小setTimeout函数的问题。jquery超时功能从来没有呼吁mouseenter mouseleave

$(this)是每个具有特定类的DOM元素。

当鼠标进入elememt,然后离开它时,没有问题。但是当鼠标直接将一个元素留给另一个元素(在500ms超时时间内)时,第一个元素(即那个,鼠标离开的元素)永远不会淡出。

因此,新的mouseenter-Event类可以防止timeOut调用该函数。 没有setTimeout-wrapper,一切都正常工作。

这里是我的代码:

$(this).hover(methods['mouseenterManager'], methods['mouseleaveManager']); 


/** 
* manage mouseenter events 
*/ 
mouseenterManager: function() { 

    clearTimeout(timer); 

    //create toolbar, if no toolbar is in dom 
    if ($(this).data("layouter").toolbar == undefined) { 

     //get bottom center of this element 
     pos_left = ($(this).width()/2) + $(this).offset().left; 
     pos_top = $(this).height() + $(this).offset().top; 

     //create toolbar element 
     toolbar = $('<div style="display:none; left:' + parseInt(pos_left) + 'px; top:' + parseInt(pos_top) + 'px;" class="layouter_bar"><ul><li><a class="edit" href="javascript:;">Edit</a></li><li><a class="copy" href="javascript:;">Edit</a></li><li><a class="remove" href="javascript:;">Edit</a></li></ul></div>'); 

     //bind this element to toolbar 
     toolbar.data("layouter", { 
      parent: $(this), 
     }); 

     //bind toolbar to this element 
     data = $(this).data("layouter"); 
     data.toolbar = toolbar; 
     $(this).data("layouter", data); 

     //bind this element to toolbar 
     data = toolbar.data("layouter"); 
     data.parent = $(this); 
     toolbar.data("layouter", data); 

     element = $(this); 
     toolbar.mouseleave(function() { 

      toolbar = $(this); 
      timer = setTimeout(function() { 
       if (!toolbar.is(":hover") && !element.is(":hover")) { 

        toolbar.fadeOut("fast", function() { 
         $(this).remove(); 
        }); 

        data = element.data("layouter"); 
        data.toolbar = undefined; 
        element.data("layouter", data); 
       } 
      }, 500); 
     }); 

     //display the toolbar 
     $("body").append(toolbar); 
     toolbar.fadeIn("fast"); 
    } 
}, 


/** 
* manage mouseleave events 
*/ 
mouseleaveManager: function() { 

    toolbar = $(this).data("layouter").toolbar; 
    element = $(this); 
    if (toolbar != undefined) { 
     timer = setTimeout(function() { 
      if (!toolbar.is(":hover")) { 

       toolbar.fadeOut("fast", function() { 
        $(this).remove(); 
       }); 

       data = element.data("layouter"); 
       data.toolbar = undefined; 
       element.data("layouter", data); 
      } 
     }, 500); 
    } 
}, 

};​ 

任何想法?

谢谢!

回答

0

它就像你正在使用大量的全局变量,当你进入另一个元素,所有这些全局变量的值,得到改变在我看来。你的超时函数引用了这些全局变量,所以当它们通过输入另一个元素而被改变时它不能正常工作。

只要你输入另一个元素,你清除计时器以防止它运行,并且因为它是一个全局计时器,所以只有一个,所以你杀死了你想要启动的计时器。

对于全局变量的问题,把var中的所有变量的前面,应该是当地这样的:

var toolbar = $(this).data("layouter").toolbar; 
var element = $(this); 

//get bottom center of this element 
var pos_left = ($(this).width()/2) + $(this).offset().left; 
var pos_top = $(this).height() + $(this).offset().top; 

对于计时器的问题,看来,我喜欢你不需要一个全局计时器,但每个元素都需要一个计时器。这有点复杂。如果没有我可以运行和测试的东西,我不能确定它是否可以在没有任何其他变化的情况下工作,但这是正确方向的步骤,以便将变量固定为本地并使计时器对每个元素都是本地的:

$(this).hover(methods['mouseenterManager'], methods['mouseleaveManager']); 


/** 
* manage mouseenter events 
*/ 
mouseenterManager: function() { 

    var self = $(this); 
    var timer = self.data("timer"); 
    if (timer) { 
     clearTimeout(timer); 
    } 

    //create toolbar, if no toolbar is in dom 
    if (self.data("layouter").toolbar == undefined) { 

     //get bottom center of this element 
     var pos_left = ($(this).width()/2) + $(this).offset().left; 
     var pos_top = $(this).height() + $(this).offset().top; 

     //create toolbar element 
     var toolbar = $('<div style="display:none; left:' + parseInt(pos_left) + 'px; top:' + parseInt(pos_top) + 'px;" class="layouter_bar"><ul><li><a class="edit" href="javascript:;">Edit</a></li><li><a class="copy" href="javascript:;">Edit</a></li><li><a class="remove" href="javascript:;">Edit</a></li></ul></div>'); 

     //bind this element to toolbar 
     toolbar.data("layouter", { 
      parent: self, 
     }); 

     //bind toolbar to this element 
     var data = self.data("layouter"); 
     data.toolbar = toolbar; 
     self.data("layouter", data); 

     //bind this element to toolbar 
     data = toolbar.data("layouter"); 
     data.parent = self; 
     toolbar.data("layouter", data); 

     var element = self; 
     toolbar.mouseleave(function() { 

      toolbar = self; 
      timer = setTimeout(function() { 
       self.data("timer", null); 
       if (!toolbar.is(":hover") && !element.is(":hover")) { 

        toolbar.fadeOut("fast", function() { 
         $(this).remove(); 
        }); 

        data = element.data("layouter"); 
        data.toolbar = undefined; 
        element.data("layouter", data); 
       } 
      }, 500); 
      self.data("timer", timer); 
     }); 

     //display the toolbar 
     $("body").append(toolbar); 
     toolbar.fadeIn("fast"); 
    } 
}, 


/** 
* manage mouseleave events 
*/ 
mouseleaveManager: function() { 

    var toolbar = $(this).data("layouter").toolbar; 
    var element = $(this); 
    var timer = element.data("timer"); 
    if (toolbar != undefined && !timer) { 
     timer = setTimeout(function() { 
      element.data("timer", null); 
      if (!toolbar.is(":hover")) { 

       toolbar.fadeOut("fast", function() { 
        $(this).remove(); 
       }); 

       var data = element.data("layouter"); 
       data.toolbar = undefined; 
       element.data("layouter", data); 
      } 
     }, 500); 
     element.data("timer", timer); 
    } 
}, 

};​ 
+0

谢谢!这是一个简单的全球/本地问题!我需要通过使用“var”将局部变量标记为本地变量。 – 2012-04-18 12:30:38

0

将要编辑的元素传递给定时器的功能。

例如:

timer = setTimeout(function(toolbar, element) { 
     if (!toolbar.is(":hover")) { 

      toolbar.fadeOut("fast", function() { 
       toolbar.remove(); 
      }); 

      data = element.data("layouter"); 
      data.toolbar = undefined; 
      element.data("layouter", data); 
     } 
    }, 500)