添加和删除带有参数的事件侦听器

新手上路,请多包涵

我正在编写一个 vanilla JavaScript 工具,启用后会向传递给它的每个元素添加事件侦听器。

我想做这样的事情:

 var do_something = function (obj) {
        // do something
    };

for (var i = 0; i < arr.length; i++) {
    arr[i].el.addEventListener('click', do_something(arr[i]));
}

不幸的是,这不起作用,因为据我所知, _在添加事件监听器时,参数只能传递给匿名函数_:

 for (var i = 0; i < arr.length; i++) {
    arr[i].el.addEventListener('click', function (arr[i]) {
        // do something
    });
}

问题是我需要能够在禁用该工具时删除事件侦听器,但我不认为可以使用匿名函数删除事件侦听器

 for (var i = 0; i < arr.length; i++) {
    arr[i].el.removeEventListener('click', do_something);
}

我知道我可以轻松地使用 jQuery 来解决我的问题,但我正在尝试尽量减少依赖性。 jQuery 必须以某种方式解决这个问题,但代码有点混乱!

原文由 tomturton 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 261
2 个回答

这是无效的:

 arr[i].el.addEventListener('click', do_something(arr[i]));

侦听器必须是函数 _引用_。当您调用函数作为 addEventListener 的参数时,函数的返回值将被视为事件处理程序。您不能在分配侦听器时指定参数。处理程序函数将始终以 event 作为第一个参数传递。要传递其他参数,您可以将处理程序包装到匿名事件侦听器函数中,如下所示:

 elem.addEventListener('click', function(event) {
  do_something( ... )
}

为了能够通过 removeEventListener 你只需命名处理函数:

 function myListener(event) {
  do_something( ... );
}

elem.addEventListener('click', myListener);

// ...

elem.removeEventListener('click', myListener);

要访问处理程序函数中的其他变量,您可以使用闭包。例如:

 function someFunc() {
  var a = 1,
      b = 2;

  function myListener(event) {
    do_something(a, b);
  }

  elem.addEventListener('click', myListener);
}

原文由 marekful 发布,翻译遵循 CC BY-SA 4.0 许可协议

// Define a wrapping function
function wrappingFunction(e) {
  // Call the real function, using parameters
  functionWithParameters(e.target, ' Nice!')
}
// Add the listener for a wrapping function, with no parameters
element.addEventListener('click', wrappingFunction);
// Save a reference to the listener as an attribute for later use
element.cleanUpMyListener = ()=>{element.removeEventListener('click', wrappingFunction);}

// ...

element.cleanUpMyListener ()

步骤 1) 为您的函数命名。

步骤 2) 保存对函数的引用(在这种情况下,将引用保存为元素本身的属性)

Step 3) 使用函数引用移除监听器

 // Because this function requires parameters, we need this solution
function addText(element, text) {
  element.innerHTML += text
}

// Add the listener
function addListener() {
  let element = document.querySelector('div')
  if (element.removeHoverEventListener){
    // If there is already a listener, remove it so we don't have 2
    element.removeHoverEventListener()
  }
  // Name the wrapping function
  function hoverDiv(e) {
      // Call the real function, using parameters
      addText(e.target, ' Nice!')
  }
  // When the event is fired, call the wrapping function
  element.addEventListener('click', hoverDiv);
  // Save a reference to the wrapping function as an attribute for later use
  element.removeHoverEventListener = ()=>{element.removeEventListener('click', hoverDiv);}
}

// Remove the listener
function removeListener() {
  let element = document.querySelector('div')
  if (element.removeHoverEventListener){
    // Use the reference saved before to remove the wrapping function
    element.removeHoverEventListener()
  }
}
 <button onclick="addListener()">Turn Listener on</button>
<button onclick="removeListener()">Turn Listener off</button>
<div>Click me to test the event listener.</div>

原文由 Richard Henage 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题