简体   繁体   English

为什么这个 eventListner 回调 function 运行了两次

[英]why this eventListner callback function is running twice

 const addons = document.querySelectorAll('.addon'); const toggleAddon = (e, addon) => { console.log(addon); console.log(addon.querySelector('input').checked); if (addon.querySelector('input').checked) addon.classList.remove('selected-plan'); else addon.classList.add('selected-plan'); }; addons.forEach((addon) => { addon.addEventListener('click', (e) => toggleAddon(e, addon)); });
 <label> <div class="addon addon-2 selected-addon"> <input type="checkbox" name="addon-2" class="addon-chkbox" id="larger-storage"> <div class="addon-info"> <h3 class="addon-name">Larger Storage</h3> <p class="addon-features">Extra 1TB of cloud save</p> </div> <div class="addon-pricing-box"> <h3 class="addon-pricing">$2/mo</h3> </div> </div> </label>

Why when I click on this element, the function toggleAddon() runs twice and in first run console.log(addon.querySelector('input').checked) comes false and on second it comes true .为什么当我点击这个元素时, function toggleAddon()运行两次,第一次运行时console.log(addon.querySelector('input').checked) false ,第二次变为true Thanks for the help.谢谢您的帮助。

This is another simplified example that will better show what I'm pointing out:这是另一个简化的示例,可以更好地展示我所指出的内容:

 let counter = 0; document.querySelector('.addon').addEventListener('click', event =>{ console.log(`[${++counter}]`); console.log(event.target); });
 <label> <div class="addon"> <input type="checkbox"> <div class="addon-info"> <h3 class="addon-name">Click here</h3> </div> </div> </label>

The problem is with the <label> element, when it is clicked, it trigger another click event on the input element within.问题出在<label>元素上,当它被点击时,它会在input元素上触发另一个click事件。

I suggest using change event instead.我建议改用change事件。

check it in codesandbox .在 codesandbox 中检查它

The whole label is for the input?整个label是为了输入? so why not listen to the input click event only which will automatically be handled by the label?那么,为什么不只监听将由 label 自动处理的输入点击事件呢? like:喜欢:

 let counter = 0; document.querySelector('.addon-input').addEventListener('click', event =>{ console.log(`[${++counter}]`); console.log(event.target); });
 <label> <div class="addon"> <input class="addon-input" type="checkbox"> <div class="addon-info"> <h3 class="addon-name">Click here</h3> </div> </div> </label>

As @Felix Kling mentioned, try to modify the related code like this and check what will happen:正如@Felix Kling 提到的,尝试像这样修改相关代码并检查会发生什么:

addons.forEach((addon) => {
  console.log( addon.getAttribute("ever-bound") );
  addon.setAttribute("ever-bound", "1"); //may be not work, it means to save some state on the element
  if( ... ) return;
  addon.addEventListener('click', (e) => toggleAddon(e, addon));
}); 

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

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