我希望在短暂的延迟后,在鼠标事件上关闭一个下拉菜单。但是我无法让它正常工作。
在对象中考虑以下方法:(我使用的是jQuery)
myObj = {};
myObj.message = "woot!";
myObj.bindEvents = function() {
var that = this;
$("#menuPanel")
.bind("mouseleave", function() {
that.timer = setTimeout(that.closeMenu,500);
});
}
myObj.closeMenu = function() {
// close the menu
alert(this.message);
}
这不起作用。也就是说,this.message未定义。经过一番挖掘,我理解为什么。 :)'that'引用在执行时不能用于setTimeout内部的代码。
我想知道,解决此类问题的“最佳”方法是什么?我怎样才能有一个使用setTimeout的方法在同一个对象中调用另一个方法,并且仍然可以访问对象中的属性?
提前感谢您的帮助。
答案 0 :(得分:4)
这里的问题是你要从它的对象中分离closeMenu方法。如果你这样做,你会遇到同样的问题:
var closeMenu = myObj.closeMenu; // detaching the method from the object
closeMenu();
分离和调用这样的方法意味着它们不再适用于它们所创建的对象。在你的例子中,你做的几乎是同样的事情:
// Setting the first parameter of setTimeout to be the detached closeMenu method
that.timer = setTimeout(that.closeMenu,500);
第一种方法的修正方法是使用call
或apply
方法:
var closeMenu = myObj.closeMenu; // detaching the method from the object
closeMenu.apply(myObj);
但这不适用于计时器。相反,创建一个匿名函数:
that.timer = setTimeout(function () { that.closeMenu(); },500);
<小时/> 也许值得一提的是
bind()
- 不要与jQuery的$('#selector').bind()
混淆 - 这种方法已经在各种博客和一些库中浮现(原型是最值得注意的)一段时间了,最终已在ECMAScript edition 5中实施。
that.timer = setTimeout(that.closeMenu.bind(that),500);
我在我创建的一个或两个类中使用了类似的方法,因为它只会让事情变得更容易。