首页 > 解决方案 > 闭包如何在 addEventListener 中工作?

问题描述

我得到了这个代码:

function getElementByName(name) {
  return document.querySelector(name);
}

function removeButton(parentToClick) {
  parentToClick.addEventListener('click', e => {
    let buttonToClick = e.target;

    const removeButton = getElementByName(`.remove`);

    removeButton.addEventListener('click', e => {
      console.log(e.target);
      remove(buttonToClick);
    });
  });
}

function remove(buttonToClick) {
  return buttonToClick.remove();
}

removeButton(getElementByName(`#menu`));
<div id="menu">
  <button data-action="save">Save</button>
  <button data-action="load">Load</button>
  <button data-action="search">Search</button>
</div>

<button class="remove">Remove</button>

当我单击“删除”按钮时,上一个单击的按钮(例如保存按钮)从关闭中取出,然后按预期将其删除。问题是当我单击另一个按钮时,例如,搜索按钮,然后单击“删除”按钮,关闭有保存按钮而不是搜索按钮。我想知道为什么会这样。

标签: javascript

解决方案


那么会发生什么:

  1. 你点击一个搜索。它绑定了一个要移除的事件监听器。
  2. 您单击删除,它会从 1 中的事件侦听器中删除搜索。
  3. 你点击保存。它绑定了一个要移除的事件监听器。
  4. 您单击删除,它会调用事件侦听器 1,并从 3 调用事件侦听器。

您假设单击事件以某种方式仅绑定到该一个元素。事实是您多次绑定点击,但它不知道它只是应该被解雇。

你能做什么?在绑定另一个事件之前删除该事件。或者更好的是,存储点击的内容并且不绑定多个事件。

function removeButton(parentToClick) {

  let buttonToClick = null;

  parentToClick.addEventListener('click', e => {
    buttonToClick = e.target.closest('button[data-action]');
  });

  const removeButton = document.querySelector('.remove');

  removeButton.addEventListener('click', e => {
    if (buttonToClick) remove(buttonToClick);
    buttonToClick = null;
  });
}

function remove(buttonToClick) {
  return buttonToClick.remove();
}

removeButton(document.querySelector('#menu'));
<div id="menu">
  <button data-action="save">Save</button>
  <button data-action="load">Load</button>
  <button data-action="search">Search</button>
</div>

<button class="remove">Remove</button>


推荐阅读