2010-02-21 32 views
2

我希望有一個下拉菜單在短暫延遲後關閉它自己的鼠標事件。但是我無法正常工作。如何讓setTimeout在對象中執行一個方法?

考慮對象以下方法:(我使用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

@Nick:問題中有jQuery。 – chelmertz 2010-02-21 13:09:05

+0

是的,對不起,我忽略提及我正在使用jQuery。 – Travis 2010-02-21 13:10:37

回答

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); 

用於第一種方法解決將是使用callapply方法:

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); 

我在創建的一個或兩個類中使用了類似的方法,因爲它使事情變得簡單。

+0

真棒。謝謝! – Travis 2010-02-21 13:40:38

+0

@ Travis:不用擔心。在發佈該評論約11秒後,我在ECMAScript第5版中添加了一些關於「bind()」方法的信息,可能對您有用:-) – 2010-02-21 13:41:42

相關問題