简体   繁体   English

如何让setTimeout在对象中执行方法?

[英]How can I have setTimeout execute a method in an object?

I would like to have a pulldown menu close itself upon a mouseleave event, after a short delay. 我想在短暂的延迟后,通过mouseleave事件关闭下拉菜单。 But I'm having trouble getting it working. 但是我很难让它工作。

Consider the following methods in an object: (I am using jQuery) 考虑对象中的以下方法:(我正在使用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 doesn't work. 这行不通。 That is to say, this.message comes up undefined. 也就是说,this.message出现未定义。 After a bit of digging, I understand why. 经过一番挖掘,我明白了为什么。 :) The 'that' reference is not available to code inside of setTimeout at the time of execution. :)'that'引用在执行时不适用于setTimeout内部的代码。

I'm wondering, what is the "best" way to get around this type of problem? 我想知道,解决此类问题的“最佳”方法是什么? How can I have a method that uses setTimeout call another method in the same object, and still have access to the properties in the object? 如何使用setTimeout的方法在同一对象中调用另一个方法,并且仍然可以访问该对象中的属性?

Thanks in advance for your help. 在此先感谢您的帮助。

The problem here is that you're detaching the closeMenu method from it's object. 这里的问题是您要从其对象分离closeMenu方法。 You would have the same problem if you did this: 如果这样做,您将遇到同样的问题:

var closeMenu = myObj.closeMenu;  // detaching the method from the object
closeMenu();

Detaching and calling methods like this means they no longer apply to the objects they were created on. 这样的分离和调用方法意味着它们不再适用于在其上创建的对象。 In your example, you're doing almost the same thing: 在您的示例中,您正在做几乎相同的事情:

// Setting the first parameter of setTimeout to be the detached closeMenu method
that.timer = setTimeout(that.closeMenu,500); 

A fix for the first method would be to use the call or apply methods: 第一种方法的解决方法是使用callapply方法:

var closeMenu = myObj.closeMenu;  // detaching the method from the object
closeMenu.apply(myObj);

But that wouldn't work for a timer. 但这对于计时器不起作用。 Instead, create an anonymous function: 而是创建一个匿名函数:

that.timer = setTimeout(function () { that.closeMenu(); },500); 


It might also be worth mentioning bind() - not to be confused with jQuery's $('#selector').bind() - a method that's been floating around on various blogs and in some libraries (Prototype being the most notable) for a while now, and has finally been implemented in ECMAScript edition 5 . 还可能值得一提的是bind() -不要与jQuery的$('#selector').bind()混淆-这种方法在各种博客和某些库中都经常出现(原型是最著名的)现在,终于在ECMAScript第5版中实现了。

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

I use a similar method in one or two classes I created, because it just makes things easier. 我在创建的一两个类中使用了类似的方法,因为它使事情变得更容易。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM