我有一个可以容纳多个可编辑内容的页面。我想在编辑内容时发出某种检查事件。
我的代码实现如下:
// Find all editable elements.
let allEditableElements = document.querySelectorAll('[contenteditable="true"]');
for(let i = 0; i < allEditableElements.length; i++){
//Remove eventListener to prevent duplicate events.
allEditableElements[i].removeEventListener('input', (event) => {myClass.myEventMethod(event);}, false);
// Add event.
allEditableElements[i].addEventListener('input', (event) => {myClass.myEventMethod(event);}, false);
}
到目前为止一切正常。但正如我所说,用户可以编辑内容,包括向页面本身添加新的可编辑内容。此时将重新设置事件,这就是我之前尝试删除event
的原因。
我的问题是为什么removeEventListener
功能无法正常工作?并且没有办法为这些事件命名如此:
// With eventNameGivenByUser an event could be removed just by its name.
addEventListener('eventTriggerName', 'eventNameGivenByUser', function(), [, options]);
当然我做了一些研究,发现代码本身就是这样的:
// Find all editable elements.
let allEditableElements = document.querySelectorAll('[contenteditable="true"]');
for(let i = 0; i < allEditableElements.length; i++){
//Remove eventListener to prevent duplicate events.
allEditableElements[i].removeEventListener('input', myClass.myEventMethod, false);
// Add event.
allEditableElements[i].addEventListener('input', myClass.myEventMethod, false);
}
但是这没有传递参数,这在动态设置中是必需的......
希望有人能告诉我,2017年有一种不错的方式而且不使用图书馆。
编辑08.02.2017:
只为好奇的人: 解决方案是不将任何参数传递给侦听器:
// as you can see there is no (event) and no arrow function either.
addEventListener('input', myClass.myEventMethod, false);
现在要做的就是调用这样的方法:
// The Parameter will be passed through anyway!
myEventMethod(event) {
/**
* Do stuff with event parameter.
*/
};
之后,可以像这样删除监听器:
removeEventListener('input', myClass.myEventMethod, false);
旁注:
我使用电子而不需要跨浏览器支持。它必须与Chromium: 56.0.2924.87
兼容。
此致,Megajin
答案 0 :(得分:3)
removeEventListener
方法至少需要两个参数:事件名称和要删除的侦听器函数。
在你的第一个例子中:
allEditableElements[i].removeEventListener('input', (event) => {myClass.myEventMethod(event);}, false);
您正在定义一个以前未附加为事件监听器的新功能,因此无法将其删除。
我不知道你的第二次尝试有什么问题:
allEditableElements[i].removeEventListener('input', myClass.myEventMethod, false);
这个应该可以正常工作。但是,您可以将两种方法结合起来:将类方法包装在函数中,并将包装的版本作为侦听器附加。您只需要有一个参考,以便以后删除:
const inputListener = (event) => { myClass.myEventMethod(event); };
let allEditableElements = document.querySelectorAll('[contenteditable="true"]');
for(let i = 0; i < allEditableElements.length; i++){
//Remove eventListener to prevent duplicate events.
allEditableElements[i].removeEventListener('input', inputListener, false);
// Add event.
allEditableElements[i].addEventListener('input', inputListener, false);
}
所有说我建议只使用事件委派。将侦听器附加到DOM中较高的元素上,并且在出现新元素时不必担心清除和重新添加事件侦听器:
const handleContentEditable = e => {
if( e.target.isContentEditable ){
console.log( 'editing ', e.target );
}
};
document.body.addEventListener('input', handleContentEditable );
答案 1 :(得分:2)
这是因为removeEventListener中的箭头函数正在创建一个新的函数引用。 removeEventListener需要引用传递给addEventListener的原始方法。
您必须在案例中保留对事件方法的引用,或者您可以动态地重新创建输入元素,这将删除所有事件侦听器。
https://developer.mozilla.org/en/docs/Web/API/Node/cloneNode
克隆节点不会复制事件侦听器,因此您可以使用它来克隆原始元素并替换它。