Skip to content Skip to sidebar Skip to footer

Event Propagation Issue

I have a series of click events which are causing me some propagation issues. The data for this container is loaded in via ajax hence the body on click method. Here's the code I ha

Solution 1:

I think what you want to happen is that the propagation is only stopped if it originated from the middle div; if it originated from the bottom div you want the event to bubble all the way to the top.

You need to call stopPropagation conditionally. If the event did not originate on or inside #bottom-div, you want to call it. You can test for this using closest:

if (!$(e.target).closest('#bottom-div').length) {
    e.stopPropagation();
}

It is better to use closest for this, rather than testing the element's id directly, because with closest it will continue to work as expected even if there are other elements (a or em, for example) within the various divs.

$(function () {
    $("body").on("click","#top-div",function(){
        console.log("top event");
    });

    $("body").on("click","#middle-div",function(e){
        if (!$(e.target).closest('#bottom-div').length) {
            e.stopPropagation();
        }
    });

    $("body").on("click","#bottom-div",function(){
        console.log("bottom event");
    });
  });
<scriptsrc="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script><divid="top-div">
  top
    <divid="middle-div">
      middle
        <divid="bottom-div">
          bottom
        </div></div></div>

Solution 2:

Bubbling works from most nested element to tree root, I think You misunderstanding it in some way. So for example click in bottom-div will:

call event on bottom-div --> call event on middle-div --> call event on top-div.

As I understand the need You want to some how check what div was clicked, so to have control on it just create single event and check clicked target like that:

$("body").on("click","#top-div",function(e){

   if ( e.target.id ==='top-div'){
     //click in top div
   }

   if ( e.target.id ==='middle-div'){
     //click in middle div
   }

   if ( e.target.id ==='bottom-div'){
     //click in bottom div
   }



});

In this proposition You know exactly which div was clicked, but it will always be the most nested one, so target will be middle-div only when will be clicked part of middle-div which is not bottom-div, it will be for example padding space, the same is with top-div it will be target only if click will be in space without child elements.

More about event bubbling You can find in http://maciejsikora.com/standard-events-vs-event-delegation/.

Solution 3:

Instead of attaching event to every div. You can consider doing it as follows check this snippet

$(document).ready(function() {
  $("body").on("click", "div", function(event) {
    console.log(event.currentTarget.id + "event");
    if (event.target.id === "middle-div") {
      event.stopPropagation()
    }
  });


});
<scriptsrc="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script><divid="top-div">
  hello
  <divid="middle-div">
    hi
    <divid="bottom-div">
      bott-mid-v
    </div></div></div>

Hope it helps

Post a Comment for "Event Propagation Issue"