Search code examples
javascriptaddeventlistenerevent-bubbling

Stop event bubbling - onclick listener


Why clicking on parent div element does the job, but clicking on the child div text Click Me! returns undefined and the page doesn't load in iframe? I used event.stopPropagation to stop bubbling but it is still the same. What is the correct way to do that, when addEvenLisneter is preferred over inline onclick ?

var panel = document.getElementsByClassName('panel');
var iframe = document.getElementById('frame');

[].forEach.call(panel, function(each) {
    each.addEventListener('click', linkClick);
});

function linkClick ( event ) {
    event.stopPropagation();
    event.preventDefault();
    iframe.src = event.target.dataset.url;
}
.panel {
    padding: 20px;
    margin: 10px;
    border: 1px solid yellow;
}

.panel div {
  display: inline;
}
<div class="panel" data-url="https://www.w3schools.com/jsref/event_preventdefault.asp">
  <div>Click Me!</div>
</div>
<iframe id="frame"></iframe>

When I console.log(event) bubble property is still set to true.


Solution

  • If you prevented the click event from bubbling from the inner div, then it would never reach the one to which you bound the event handler and your function would not fire at all.

    The problem here is that event.target matches the element that was actually clicked on. You want event.currentTarget if you want to get the element that the event handler was bound to.

    var panel = document.getElementsByClassName('panel');
    var iframe = document.getElementById('frame');
    
    [].forEach.call(panel, function(each) {
        each.addEventListener('click', linkClick);
    });
    
    function linkClick ( event ) {
        event.stopPropagation();
        event.preventDefault();
        iframe.src = event.currentTarget.dataset.url;
    }
    .panel {
        padding: 20px;
        margin: 10px;
        border: 1px solid yellow;
    }
    
    .panel div {
      display: inline;
    }
    <div class="panel" data-url="https://www.w3schools.com/jsref/event_preventdefault.asp">
      <div>Click Me!</div>
    </div>
    <iframe id="frame"></iframe>