2011-10-08 120 views
4

我有一個類創建一個DOM元素,並且必須捕獲所有的點擊事件。如何在事件處理程序中訪問`this`?

簡化代碼:

function myClass() 
{ 
    this.domElement = document.createElement("canvas"); 
    this.domElement.addEventListener("click", this.handleClick); 
} 
myClass.prototype.handleClick = function(evt) 
{ 
    alert("Clicked!"); 
    // How to modify `this` object? 
} 

現在我想修改myClass的實例的一些屬性和變量handleClick()。但是this當然是指畫布對象。

問題:如何在事件處理程序中訪問對象的this

回答

3

這可以通過關閉到您的實例的引用來完成,並使用適用於強制函數的範圍:

在步驟1我有你的例子示出了如何this是被點擊的元件:http://jsfiddle.net/JAAulde/GJXpQ/

在第2步中,我有一個例子,它在您的構造函數中存儲對您的實例的引用,然後將匿名函數設置爲點擊處理程序,並將您的點擊方法從存儲的引用中調用。 http://jsfiddle.net/JAAulde/GJXpQ/1/這會導致您的點擊處理程序中的this成爲您的實例,如果您不需要訪問被點擊的元素,它將爲您工作。

在步驟3中,我存儲了相同的引用,並使用了一個匿名函數,但在該函數中,我獲取了在點擊時進入匿名函數的參數,我將這個實例的引用添加到這些參數中,在clicked元素的範圍內調用click處理程序並傳遞新的參數集。 http://jsfiddle.net/JAAulde/GJXpQ/2/使用此方法,在點擊處理程序中,我可以通過this訪問點擊元素,並通過instance訪問myClass的實例。

我希望這會有所幫助。這可能會讓人困惑,所以如果需要的話可以提問。

+0

非常感謝三種解決方案!我喜歡最好的解決方案2(好,簡單)。但是出於這個原因,我需要訪問原來的'this'?當我想訪問DOM元素時,我通過'evt.target'來完成。 – ComFreek

+0

這只是一個偏好問題,並且是如何編寫代碼的問題。如果你喜歡2並且使用合法的'evt.target'。但是,如果您正在調整現有的代碼,那麼在需要不同範圍的情況下,最終可能會出現這種情況,所以3在這種情況下可能會更好。 – JAAulde

+0

好的,謝謝。我正在編寫自己的框架,所以在這方面沒有任何問題。接受答案;) – ComFreek

2

你可以這樣說:

function myClass() { 
    var self = this; 

    this.domElement = document.createElement("canvas"); 
    this.domElement.addEventListener("click", function(evt){ 
     // use self here 
    }); 
} 

由於聽衆實際上是一個閉合,它保持參考變量self,這是反對你觀察。當你計算出實際的this時,引用了canvas元素。

另一種方式倒是工作,並保持方法分隔:

function myClass(){ 
    var self = this; 

    this.domElement = document.createElement("canvas"); 
    this.domElement.addEventListener("click", function(evt){ 
    myClass.prototype.call(self, evt); 
    }); 
} 
myClass.prototype.handleClick = function(evt){ 
    alert("Clicked!"); 
    // How to modify `this` object? 
} 

現在這一個使用Function.call和分配什麼this引用。

+0

謝謝!我更新了示例以測試對「this」的訪問:http://jsfiddle.net/StWu9/。 – ComFreek

1

您可以使用.bind,該值將預設值「this」凍結:http://jsfiddle.net/TKAHg/

.bind返回一個新功能,它與原始功能做同樣的事情,但它設置了this,以便您可以依靠它作爲您提供的值。

雖然.bind在舊版本的瀏覽器上不可用,MDC has a shim for it

// bind 'this' value inside handleClick when clicked 
this.domElement.addEventListener("click", this.handleClick.bind(this)); 
+0

謝謝!我已經更新了示例,因此該元素是可點擊的:http://jsfiddle.net/TKAHg/1/。 舊的瀏覽器沒有問題,因爲我使用畫布元素。但我需要支持Opeara和Safari。 – ComFreek

相關問題