简体   繁体   English

闭包如何在 addEventListener 中工作?

[英]how do closures work inside addEventListener?

I got this code:我得到了这段代码:

 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>

When I click on the "remove" button the previous clicked one, for example, the save button, is taken from closure and then it's removed as expected.当我单击“删除”按钮时,上一个单击的按钮(例如保存按钮)将从关闭中取出,然后按预期将其删除。 The problem is when I cliсk on another button, for instance, the search button and then click on the "remove" button, the closure has the save button rather than the search button.问题是当我点击另一个按钮时,例如搜索按钮,然后点击“删除”按钮,闭包有保存按钮而不是搜索按钮。 I'd like to know why it happens.我想知道为什么会这样。

So what happens:那么会发生什么:

  1. You click on a search.你点击一个搜索。 It binds an event listener to remove.它绑定一个事件侦听器以删除。
  2. You click on remove, it removes search from event listener in 1.您单击删除,它会从 1 中的事件侦听器中删除搜索。
  3. You click on save.你点击保存。 It binds an event listener to remove.它绑定一个事件侦听器以删除。
  4. You click on remove, it calls the event listener 1, and calls event listener from 3.您单击删除,它调用事件侦听器 1,并从 3 调用事件侦听器。

You are assuming that somehow the click event is only bound to that one element.您假设点击事件以某种方式仅绑定到该元素。 The fact is you bound the click multiple times and it has no clue it is only supposed to be fired.事实是你多次绑定了点击,它不知道它应该被触发。

What can you do?你能做什么? Remove the event before binding another.在绑定另一个之前删除事件。 Or better, store what is clicked and do not bind multiple events.或者更好的是,存储单击的内容并且不绑定多个事件。

 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>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM