3

在短暂的延迟后,我想让一个下拉菜单在鼠标离开事件时自行关闭。但我无法让它工作。

考虑对象中的以下方法:(我正在使用 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 出现 undefined。经过一番挖掘,我明白了为什么。:) 执行时 setTimeout 内部的代码无法使用“那个”引用。

我想知道,解决此类问题的“最佳”方法是什么?如何让一个使用 setTimeout 的方法在同一个对象中调用另一个方法,并且仍然可以访问该对象中的属性?

在此先感谢您的帮助。

4

1 回答 1

5

这里的问题是您要从它的对象中分离 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); 

第一种方法的修复是使用callorapply方法:

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 版本 5中实现。

that.timer = setTimeout(that.closeMenu.bind(that),500);

我在我创建的一两个类中使用了类似的方法,因为它只是让事情变得更容易。

于 2010-02-21T13:12:28.687 回答