当事件处理程序是原型函数时如何使用 removeEventListener?
How to use removeEventListener when event handler is a prototype function?
这是 question 的后续。问题是我对 removeEventListener
的调用不起作用。我必须在下面进行哪些更改才能使其正常工作?
我的自定义对象:
//Custom Editor Example with event listeners
var CE = function (id) {
'use strict';
// assume not a valid object
this.isValid = false;
this.element = document.getElementById(id);
if (this.element !== null) {
this.id = id;
this.init();
this.isValid = true;
}
};
CE.prototype.addEvent = function (event, callback, caller) {
'use strict';
// check for modern browsers first
if (typeof window.addEventListener === 'function') {
return caller.element.addEventListener(event, function (e) {callback.call(caller, e); }, false);
}
// then for older versions of IE
return this.element.attachEvent('on' + event, function (e) {callback.call(caller, window.event); });
};
CE.prototype.init = function () {
'use strict';
this.addEvent('keydown', this.onCustomKeyDown, this);
// add other event listeners
};
这就是我尝试删除事件处理程序的方式:
CE.prototype.removeEvent = function (event, callback, caller) {
'use strict';
caller.element.removeEventListener(event, callback, false);
};
CE.prototype.destroy = function () {
'use strict';
this.removeEvent('keydown', this.onCustomKeyDown, this);
// remove other event listeners
};
这是处理事件的原型函数的签名。
CE.prototype.onCustomKeyDown = function onCustomKeyDown(e) {
如果我没理解错的话,removeEventListener 不能用于删除作为匿名函数的事件处理程序。是这里的问题吗?我是否需要更改我的呼叫方式 addEventListener
?
If I understand correctly, removeEventListener cannot be used to remove event handlers which are anonymous functions. Is that the issue here?
是的。添加的函数是匿名函数表达式,不是callback
,所以用callback
调用removeEventListener
是不行的。
Do I need to change the way I'm calling addEventListener?
是的,您需要以某种方式保留对实际处理程序函数的引用,以便稍后可以将其传递给 removeEventListener
。基本上有两种方法可以做到这一点:
- 使用闭包和 return 来自
addEvent
的 remover
函数将取消订阅。
- 在某处存储对事件处理程序的引用,以便您可以在调用
removeEvent
方法时通过回调识别它 - 并确保它不会泄漏。
谢谢@Bergi。
这是他回答中的选项 #2。你可以试试这个 JSFIDDLE.
//Custom Editor Example with event listeners
var CE = function (id) {
'use strict';
// assume not a valid object
this.isValid = false;
this.element = document.getElementById(id);
if (this.element !== null) {
this.id = id;
this.customKeyDownHandler = null;
this.customFocusHandler = null;
this.init();
this.isValid = true;
}
};
/**
* Initialize an event listener
*/
CE.prototype.addEvent = function (event, callback, caller) {
'use strict';
var handler;
// check for modern browsers first
if (typeof window.addEventListener === 'function') {
this.element.addEventListener(event, handler = function (e) {
callback.call(caller, e);
}, false);
return handler;
}
// then for older versions of IE
this.element.attachEvent('on' + event, handler = function (e) {
callback.call(caller, window.event);
});
return handler;
};
/**
* init object
*/
CE.prototype.init = function () {
'use strict';
this.customKeyDownHandler = this.addEvent('keydown', this.onCustomKeyDown, this);
this.customFocusHandler = this.addEvent('focus', this.onCustomFocus, this);
};
/**
* remove an event listener
*/
CE.prototype.removeEvent = function (event, callback) {
'use strict';
this.element.removeEventListener(event, callback, false);
};
/**
* destroy object
*/
CE.prototype.destroy = function () {
'use strict';
this.removeEvent('keydown', this.customKeyDownHandler);
this.customKeyDownHandler = null;
this.removeEvent('focus', this.customFocusHandler);
this.customFocusHandler = null;
};
/**
* keydown event handler responds to arrow keys
*/
CE.prototype.onCustomKeyDown = function (e) {
'use strict';
// if (e.keyCode === 46) { e.preventDefault(); alert("Del key is invalid"); return false; }
alert("Hey, easy there! Not so hard!");
return true;
};
/**
* focus event handler
*/
CE.prototype.onCustomFocus = function (e) {
'use strict';
// if (e.keyCode === 46) { e.preventDefault(); alert("Del key is invalid"); return false; }
alert("Welcome!");
return true;
};
ce = new CE('myID'); // allocate custom editor
// do something
// input element will have default behavior, event handlers are removed
ce.destroy();
这是 question 的后续。问题是我对 removeEventListener
的调用不起作用。我必须在下面进行哪些更改才能使其正常工作?
我的自定义对象:
//Custom Editor Example with event listeners
var CE = function (id) {
'use strict';
// assume not a valid object
this.isValid = false;
this.element = document.getElementById(id);
if (this.element !== null) {
this.id = id;
this.init();
this.isValid = true;
}
};
CE.prototype.addEvent = function (event, callback, caller) {
'use strict';
// check for modern browsers first
if (typeof window.addEventListener === 'function') {
return caller.element.addEventListener(event, function (e) {callback.call(caller, e); }, false);
}
// then for older versions of IE
return this.element.attachEvent('on' + event, function (e) {callback.call(caller, window.event); });
};
CE.prototype.init = function () {
'use strict';
this.addEvent('keydown', this.onCustomKeyDown, this);
// add other event listeners
};
这就是我尝试删除事件处理程序的方式:
CE.prototype.removeEvent = function (event, callback, caller) {
'use strict';
caller.element.removeEventListener(event, callback, false);
};
CE.prototype.destroy = function () {
'use strict';
this.removeEvent('keydown', this.onCustomKeyDown, this);
// remove other event listeners
};
这是处理事件的原型函数的签名。
CE.prototype.onCustomKeyDown = function onCustomKeyDown(e) {
如果我没理解错的话,removeEventListener 不能用于删除作为匿名函数的事件处理程序。是这里的问题吗?我是否需要更改我的呼叫方式 addEventListener
?
If I understand correctly, removeEventListener cannot be used to remove event handlers which are anonymous functions. Is that the issue here?
是的。添加的函数是匿名函数表达式,不是callback
,所以用callback
调用removeEventListener
是不行的。
Do I need to change the way I'm calling addEventListener?
是的,您需要以某种方式保留对实际处理程序函数的引用,以便稍后可以将其传递给 removeEventListener
。基本上有两种方法可以做到这一点:
- 使用闭包和 return 来自
addEvent
的remover
函数将取消订阅。 - 在某处存储对事件处理程序的引用,以便您可以在调用
removeEvent
方法时通过回调识别它 - 并确保它不会泄漏。
谢谢@Bergi。
这是他回答中的选项 #2。你可以试试这个 JSFIDDLE.
//Custom Editor Example with event listeners
var CE = function (id) {
'use strict';
// assume not a valid object
this.isValid = false;
this.element = document.getElementById(id);
if (this.element !== null) {
this.id = id;
this.customKeyDownHandler = null;
this.customFocusHandler = null;
this.init();
this.isValid = true;
}
};
/**
* Initialize an event listener
*/
CE.prototype.addEvent = function (event, callback, caller) {
'use strict';
var handler;
// check for modern browsers first
if (typeof window.addEventListener === 'function') {
this.element.addEventListener(event, handler = function (e) {
callback.call(caller, e);
}, false);
return handler;
}
// then for older versions of IE
this.element.attachEvent('on' + event, handler = function (e) {
callback.call(caller, window.event);
});
return handler;
};
/**
* init object
*/
CE.prototype.init = function () {
'use strict';
this.customKeyDownHandler = this.addEvent('keydown', this.onCustomKeyDown, this);
this.customFocusHandler = this.addEvent('focus', this.onCustomFocus, this);
};
/**
* remove an event listener
*/
CE.prototype.removeEvent = function (event, callback) {
'use strict';
this.element.removeEventListener(event, callback, false);
};
/**
* destroy object
*/
CE.prototype.destroy = function () {
'use strict';
this.removeEvent('keydown', this.customKeyDownHandler);
this.customKeyDownHandler = null;
this.removeEvent('focus', this.customFocusHandler);
this.customFocusHandler = null;
};
/**
* keydown event handler responds to arrow keys
*/
CE.prototype.onCustomKeyDown = function (e) {
'use strict';
// if (e.keyCode === 46) { e.preventDefault(); alert("Del key is invalid"); return false; }
alert("Hey, easy there! Not so hard!");
return true;
};
/**
* focus event handler
*/
CE.prototype.onCustomFocus = function (e) {
'use strict';
// if (e.keyCode === 46) { e.preventDefault(); alert("Del key is invalid"); return false; }
alert("Welcome!");
return true;
};
ce = new CE('myID'); // allocate custom editor
// do something
// input element will have default behavior, event handlers are removed
ce.destroy();