removeEventlistener与箭头功能和参数无法正常工作

Meg*_*jin 3 javascript ecmascript-6

我有一个页面,可以容纳多个可编辑的内容。每当内容被编辑时,我都想触发某种检查事件。

我实现此目的的代码如下所示:

// 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);
} 
Run Code Online (Sandbox Code Playgroud)

到目前为止一切正常。但是正如我所说,用户可以编辑内容,包括向页面本身添加新的可编辑内容。届时事件将再次被设置,这就是为什么我尝试event事先删除事件的原因。

我的问题是为什么该removeEventListener功能不能按预期工作?并没有办法像这样给定事件命名:

// With eventNameGivenByUser an event could be removed just by its name.
addEventListener('eventTriggerName', 'eventNameGivenByUser', function(), [, options]);
Run Code Online (Sandbox Code Playgroud)

当然,我做了一些研究,发现代码本身可以像这样工作:

// 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);
} 
Run Code Online (Sandbox Code Playgroud)

但是,这没有传递参数,而在这种动态设置中这是必须的.​​..

希望有人能告诉我,2017年有一种不错且体面的方式,无需使用库。


编辑08.02.2017:

仅出于好奇:解决方案是不将任何参数传递给侦听器:

// as you can see there is no (event) and no arrow function either.
addEventListener('input', myClass.myEventMethod, false);
Run Code Online (Sandbox Code Playgroud)

现在要做的就是调用prepare方法,如下所示:

// The Parameter will be passed through anyway!
myEventMethod(event) {

      /**
      * Do stuff with event parameter.
      */

};
Run Code Online (Sandbox Code Playgroud)

之后,可以这样删除监听器:

removeEventListener('input', myClass.myEventMethod, false);
Run Code Online (Sandbox Code Playgroud)

边注:

我正在使用电子,不需要跨浏览器支持。它只需要与兼容Chromium: 56.0.2924.87

此致Megajin

paw*_*wel 5

removeEventListener方法至少需要两个参数:事件名称和要删除的侦听器函数。

在第一个示例中:

  allEditableElements[i].removeEventListener('input', (event) => {myClass.myEventMethod(event);}, false);
Run Code Online (Sandbox Code Playgroud)

您正在定义一个以前未作为事件侦听器附加的新功能,因此无法将其删除。

我不知道您的第二次尝试出了什么问题:

allEditableElements[i].removeEventListener('input', myClass.myEventMethod, false);
Run Code Online (Sandbox Code Playgroud)

这应该工作正常。但是,您可以结合使用这两种方法:将类方法包装在函数中,并将包装的版本附加为侦听器。您只需要提供参考,便可以稍后将其删除:

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);
} 
Run Code Online (Sandbox Code Playgroud)

所有这些,我建议您仅使用事件委托。将侦听器附加到DOM中较高的元素上,不必担心在出现新元素时清除并重新添加事件侦听器:

const handleContentEditable = e => {
    if( e.target.isContentEditable ){
        console.log( 'editing ', e.target );
    }
};

document.body.addEventListener('input', handleContentEditable );
Run Code Online (Sandbox Code Playgroud)

https://jsfiddle.net/rd3y9gh9/1/