Skip to content
Advertisement

Why is JavaScript sending an element to my event handler, when that element has no event?

This html:

<span id="mySpan"><img src="images/picture.png" alt="Some nice alt text" />
 Link text</span>

This JavaScript takes the span containing the image and text, then makes it clickable:

spanVar = document.getElementById("mySpan");
spanVar.addEventListener("click", myEvent, false);
   
function myEvent(e){
 var obj = e.target;
}

If I click on the “Link text,” then the obj in myEvent() is the span. If I click on the image, then the obj is the image element! The image itself has no event. So why isn’t it always the span that gets passed to the event handler?

This is trimmed down so that it only works in Firefox for the sake of simplicity, by the way.

Also, please feel free to edit my question title if you can formulate it more coherently.

Advertisement

Answer

Events are effectively inherited.

When an event handler is added to an element, then all the children also are affected by that event handler, since they are inside the element. So you must deal with events carefully.

In your case, you just really want to check what is being clicked on inside myEvent:

spanVar = document.getElementById("mySpan");
spanVar.addEventListener("click", myEvent, false);

function myEvent(e){
    if (e.target === spanVar) // This will make the img non clickable
        var obj = e.target;
}

Try it out with this jsFiddle


If you want to retrieve the element that originally had the click handler attached to it, then simply use this

spanVar = document.getElementById("mySpan");
spanVar.addEventListener("click", myEvent, false);

function myEvent(e){
    var obj = this;  // This is the object that had the click handler attached
}

Try it out with this jsFiddle


The problem really isn’t event bubbling. It’s that all child elements of a parent element effectively receive the event handlers of their parent element. Event bubbling would come into play if the child and parent had different handlers attached, but you only wanted to fire the handler of the child.

Another solution is to change your HTML:

<div>
    <img src="images/picture.png" alt="Some nice alt text" />
    <span id="mySpan">Link text</span>
</div>
User contributions licensed under: CC BY-SA
5 People found this is helpful
Advertisement