简体   繁体   中英

Click event on div with img and text not firing when clicking img

I wrote toggle script in ES6/vanilla JS. The intended functionality is super simple, you click on the toggle div and it adds an active class to another div that matches the toggle div's data-toggle property. In my toggle div, I need there to be both text and an image. It works great when you click on the text within the div, but when you click on the image within the div, the toggle is not firing. Is there something specific I need to do to include all of the children within the div?

For some reason, I can't even get this working via this code snippet editor, but it is working in my project.

 const setActive = (toggles, panels, id) => { let activePanel = panels.filter(panel => panel.getAttribute('data-toggle') == id) let activeToggle = toggles.filter(toggle => toggle.getAttribute('data-toggle') == id) activePanel.forEach(panel => panel.classList.add('active')) activeToggle.forEach(toggle => toggle.classList.add('active')) } const removeActive = (nodes) => { nodes.forEach(node => node.classList.remove('active')) } const handler = (event) => { event.preventDefault() let id = event.target.getAttribute('data-toggle') let panels = Array(...document.querySelectorAll('.js-toggle-panel')) let toggles = Array(...document.querySelectorAll('.js-toggle')) removeActive(panels) removeActive(toggles) setActive(toggles, panels, id) } let toggles = Array(...document.querySelectorAll('.js-toggle')) toggles.forEach(toggle => toggle.addEventListener('click', handler)) 
 .toggle-panel { display: none; } .toggle-panel .active { display: block; } 
 <div class="js-toggle toggle" data-toggle="toggle-1"> <img src="https://via.placeholder.com/50"> First toggle </div> <div class="js-toggle toggle" data-toggle="toggle-2"> Second toggle </div> <div class="js-toggle-panel toggle-panel" data-toggle="toggle-1"> <h1>Toggle 1</h1> </div> <div class="js-toggle-panel toggle-panel" data-toggle="toggle-2"> <h1>Second toggle!</h1> </div> 

Instead of event.target you should use event.currentTarget in your handler function to return node to which event listener is attached. event.target is returning <img> node, not <div> with data-toggle in your case.

I changed two things that I believe will resolve your issue:

  1. I changed the selector .toggle-panel .active to .toggle-panel.active -- without that, even in the cases where the JS was working as you intended nothing was actually be made visible.
  2. I moved your code from using event.target to event.currentTarget -- the former always points to the clicked element, whereas the latter refers to the element on which the listener has been placed.

See the snippet below.

 const setActive = (toggles, panels, id) => { let activePanel = panels.filter(panel => panel.getAttribute('data-toggle') == id) let activeToggle = toggles.filter(toggle => toggle.getAttribute('data-toggle') == id) activePanel.forEach(panel => panel.classList.add('active')) activeToggle.forEach(toggle => toggle.classList.add('active')) } const removeActive = (nodes) => { nodes.forEach(node => node.classList.remove('active')) } const handler = (event) => { event.preventDefault() let id = event.currentTarget.getAttribute('data-toggle') let panels = Array(...document.querySelectorAll('.js-toggle-panel')) let toggles = Array(...document.querySelectorAll('.js-toggle')) removeActive(panels) removeActive(toggles) setActive(toggles, panels, id) } let toggles = Array(...document.querySelectorAll('.js-toggle')) toggles.forEach(toggle => toggle.addEventListener('click', handler)) 
 .toggle-panel { display: none; } .toggle-panel.active { display: block; } 
 <div class="js-toggle toggle" data-toggle="toggle-1"> <img src="https://via.placeholder.com/50"> First toggle </div> <div class="js-toggle toggle" data-toggle="toggle-2"> Second toggle </div> <div class="js-toggle-panel toggle-panel" data-toggle="toggle-1"> <h1>Toggle 1</h1> </div> <div class="js-toggle-panel toggle-panel" data-toggle="toggle-2"> <h1>Second toggle!</h1> </div> 

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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