通常我在JavaScript中使用对象来保存数据,但事件监听器不允许辅助指针检索这些对象。
在事件回调中检索对象指针的最佳方法是什么? (请不要第三方图书馆)
示例:
function MyClass()
{
this.number = Math.random();
this.button = document.createElement('div');
this.button.appendChild(document.createTextNode('Show number'));
document.body.appendChild(this.button);
// THIS FOLLOWING LINE REQUIRE CHANGES
this.button.addEventListener('click', MyClass.prototype.listener);
}
MyClass.prototype.listener = function (e)
{
// HERE, "THIS" DO NOT POINT TO MY OBJECT
alert( this.number );
}
testMyClass1 = new MyClass();
testMyClass2 = new MyClass();
目前,我使用静态数组来保存指针,但这很难维护:
//New constructor, first try
function MyClass()
{
this.number = Math.random();
this.button = document.createElement('div');
this.button.appendChild(document.createTextNode('Show number'));
document.body.appendChild(this.button);
if (undefined===MyClass.prototype.register) MyClass.prototype.register = [];
this.id = MyClass.prototype.register.length;
MyClass.prototype.register.push(this);
this.callback = new Function( 'e',
'var self = MyClass.prototype.register[' + this.id + '];'+
'MyClass.prototype.listener.call(self, e);'
);
this.button.addEventListener('click', this.callback);
}
注意:
答案 0 :(得分:5)
如果使用ES5:
this.button.addEventListener('click', MyClass.prototype.listener.bind(this));
如果不使用ES5,get a shim用于Function.bind
。
请注意,这确实会创建一个新的函数对象作为类的每个实例的处理程序,但是没有简单的方法可以避免这种情况。
答案 1 :(得分:2)
您可以使用Function.bind
设置事件处理程序的上下文
function MyClass()
{
this.number = Math.random();
this.button = document.createElement('div');
this.button.appendChild(document.createTextNode('Show number'));
document.body.appendChild(this.button);
// THIS FOLLOWING LINE WAS CHANGED
this.button.addEventListener('click', MyClass.prototype.listener.bind(this));
}
MyClass.prototype.listener = function (e)
{
// HERE, "THIS" DO NOT POINT TO MY OBJECT
alert( this.number );
}
testMyClass1 = new MyClass();
testMyClass2 = new MyClass();
答案 2 :(得分:1)
一种非常简单和优雅的方法是使您的对象实现EventListener接口。
为此,您的对象只需要handleEvent()
方法。
MyClass.prototype.handleEvent = function(event) {
switch (event.type) {
case "click":
return this.listener(event);
default:
throw "No handler for " + event.type
}
}
然后你只需传递对象本身。
// v--pass the object instead of a function
this.button.addEventListener('click', this);
this
中的handleEvent
是预期的对象,因此您只需调用对象方法即可。
答案 3 :(得分:0)
您可以简单地使用函数创建一个包含较少参数的包装器。换句话说,
变化:
this.button.addEventListener('click', MyClass.prototype.listener);
要:
var self = this;
this.button.addEventListener('click', function() { self.listener(); });