2011-03-30 151 views
40

我知道這個問題沒有多大意義,但讓我試着澄清一下。如何將此上下文傳遞給事件處理函數?

我有一個類,叫做ScrollBanner,它看起來有點如下(略去了很多):

function ScrollBanner() { 
    this.initialize = function(selector) { 
     $('span#banner1-nav').click(this._onClickNavigation); 
    } 

    this._onClickNavigation = function(event) { 
     this.restartTimer(); // this == span#banner1-nav element from this.initialize 
     //... 
    } 

    this.restartTimer() { 
     //... 
    } 
} 

正如你可以看到this.initialize設置一個單擊處理程序這一點。 _onClickNavigation。有些人可能會期望這個裏面的事件處理程序引用ScrollBanner實例,但遺憾的是它沒有。它指的是trigerred click事件,在這種情況下跨度#banner1-NAV

會是怎樣的最好的方式得到這個來指代ScrollBanner類實例的元素?

回答

73

舊的/傳統的方式:

捕捉this在一個變量:

this.initialize = function(selector) { 
    var that = this; 
    $('span#banner1-nav').click(function(event) { 
     that._onClickNavigation(event); 
    }); 
} 

你也可以指定this一個變量如instance

function ScrollBanner() { 
    var instance = this; 
    // ... 
} 

,並參考instance而不是this中的所有電話。

總體思路是將this存儲在更高範圍的變量中。


的ECMAScript5方式:

ECMAScript5介紹的功能的新屬性:.bind()MDC's documentation顯示不支持它的瀏覽器的實現。有了它,你可以綁定一個特定的上下文功能:

this.initialize = function(selector) { 
    $('span#banner1-nav').click(this._onClickNavigation.bind(this)); 
} 

但在幕後它是做同樣的事情。好處是您可以在支持的瀏覽器中使用內置功能。

請注意,這不同於applycall。這兩個設置上下文執行該功能,而bind只設置上下文而不執行該功能。


jQuery的方式:

jQuery提供了一種方法$.proxy()正在做同樣的:

$('span#banner1-nav').click($.proxy(this._onClickNavigation, this)); 
+0

良好的通話,我一般做分配'VAR是= this'我構造的頂部,這樣的習慣你總是有一個參考。然後一直使用'that',這樣就不會產生混淆(當然假定你引用了這個,而不是其他的) – brad 2011-03-30 18:30:21

+2

這很有用,但是感覺很髒。 :) – 2011-03-30 18:30:36

+0

@JoeZephyr:就是這樣;)請看看我的更新了。 – 2011-03-30 18:36:39

1

我知道這是一個老問題,但我看到,在該評論,$ .proxy()被提及。是的,它確實會改變對象的上下文,但不會改變jQuery事件。

$('.selector').click($.proxy(function() { 
    console.log(this); /* this is set to .selector */ 
}, this)); 

$ .proxy()返回this下文稱在範圍的功能,但是,則返回並通過click()然後改變範圍.selector元件中使用該功能。

我一分鐘前測試,但如果我聽錯了,請不要告訴

+4

不知道這是不是在舊的jQuery版本,但這個例子顯示你是錯的:http://jsfiddle.net/mazztgc9/。 – 2015-07-08 10:19:58

相關問題