2011-10-08 80 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

相关问题