I have a pretty basic Bootstrap button on my page. I have an event listener listening for clicks on this button. I have an image tag as the content of the button. When a user clicks the button, the event listener fires as desired. However, if the button click lands on the image within the button, the image intercepts the click and the button click event listener doesn’t fire. How can I get the button to detect a click on both itself, and its content (e.g. the image tag)?
<button type="button" class="btn btn-custom" id="navLogoButtonLeft">
<!-- dev tools indicate clicks land on this <img> and never make it to the <button> -->
<img class="icon" src="img/icon.png">
</button>
Note, this is a Twitter Bootstrap button, but I’m not sure that has any bearing on the problem.
Here is the JS, by request.
var navLogoButtonLeft;
function initNav() {
navLogoButtonLeft = document.getElementById('navLogoButtonLeft');
// note, I've tried both 'true' and 'false' here
navLogoButtonLeft.addEventListener('click', handleClick, true);
}
// this method does fire, but clickEvent is the <img>, not the <button>
function handleClick(clickEvent) {
if(clickEvent.target == navLogoButtonLeft) {
// this line cannot be reached
window.location = './';
return;
}
}
window.addEventListener('load', initNav, false);
3
Answers
you could just add the same event listener to the image tag to get the desired effect.
Though you could also go to a more technical level
and add a class that sets
pointer-events: none;
in the CSS and add that class to the end of your img tagTry do the inverse (and using the bubble effect) then try apply the listner to the img (in my sample I simply change the position of the id associated the listener)
Your dev tools are correct. When you click on the image in your button, the event target actually is the image. Nevertheless, the click event should bubble up and finally make the button’s event listener fire.
So, if your HTML is correct (the
//
comments for example would break it), and you correctly added the event listener likethe event listener should fire on click on the button as well as on any of its child elements.
ev.stopPropagation();
in the handler stops the event from bubbling up any further. See a working example here: https://jsfiddle.net/quj56hq5/If you have to set
pointer-events: none;
for this to work, there’s definitely something wrong with your code or some Twitter Bootstrap JS gets in the way.Update
After the JS was added by the question’s author the real cause of the problem showed. It is the line
that keeps the handler’s code from being executed when the image is clicked, because
.target
always is the clicked element while.currentTarget
always is the element the listener was originally attached to.