2

In my code, I have added onclick on parent div and want to perform other action on inner div, but clicking on inner div also triggering parent click. how to stop that?

$(document).on('click', '.child', function(e) {
  e.preventDefault();
  e.stopPropagation();
  console.log('child');
});

function parentfun(sender) {
  console.log('parent');
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="parent" onclick="parentfun(this)">
  parent
  <div class="child">child</div>
</div>
Above divs are generated on run time on some other event.

Clicking on child, also trigger parent's click. preventDefault & stopPropagation are not working.

FYI: my question is different than How do I prevent a parent's onclick event from firing when a child anchor is clicked?

Jitendra Pancholi
  • 7,897
  • 12
  • 51
  • 84
  • Possible duplicate of [How do I prevent a parent's onclick event from firing when a child anchor is clicked?](https://stackoverflow.com/questions/1369035/how-do-i-prevent-a-parents-onclick-event-from-firing-when-a-child-anchor-is-cli) – KhorneHoly Sep 04 '18 at 07:19
  • jQuery uses its own implementation of native events, have you checked if that is the reason? – connexo Sep 04 '18 at 07:19

4 Answers4

5

What you are actually doing here is binding the click-event to the document, not the child-element. So the event has already bubbled up all the way to the document, it's too late to try to stop the bubbling with stopPropagation.

See here when I change the click-handler to the child instead:

$(".child").on('click', function(e) {
  e.preventDefault();
  e.stopPropagation();
  console.log('child');
});

function parentfun(sender) {
  console.log('parent');
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="parent" onclick="parentfun(this)">
  parent
  <div class="child">child</div>
</div>

Edit

As the question changed a bit, here is what you can do (for example) if the elements are created dynamically:

  $(document).on('click', '.parent, .child', function(e) {
    e.stopPropagation();
    if ($(this).is(".child")) {
      console.log('child');
    } else {
      console.log('parent');
    }
  });
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="parent">
  parent
  <div class="child">child</div>
</div>
Esko
  • 4,109
  • 2
  • 22
  • 37
0

Using plain vanilla JS it works as expected:

function logEventTarget(e) {
  e.stopPropagation();
  console.log(e.target.id);
}

parentDiv.addEventListener('click', logEventTarget)
childDiv.addEventListener('click', logEventTarget)
<div id="parentDiv">
  parent
  <div id="childDiv">child</div>
</div>

Using an inline event handler won't pass the event to the handler function:

function logEventTarget(e) {
  e.stopPropagation();
  console.log(e.target.id);
}

childDiv.addEventListener('click', logEventTarget)
<div id="parentDiv" onclick="logEventTarget()">
  parent
  <div id="childDiv">child</div>
</div>

One of the many reasons you shouldn't use inline event handlers at all. Note that e.stopPropagation() still works for the childDiv.

connexo
  • 53,704
  • 14
  • 91
  • 128
0

You can notice that when clicking the chlid element the parent triggers first (that is why parent prints first then child ) because of event capturing which precedes event bubbling. In-order to stop the event capturing phase from parent you can stop propagating that event and then only child event will trigger.

$(document).on('click', '.child', function(e) {
  //e.preventDefault();
  e.stopPropagation();
  console.log('child');
});

$(document).on('click', '.parent', parentfun);
function parentfun(e) {
  e.stopPropagation();
  console.log('parent');
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="parent">
  parent
  <div class="child">child</div>
</div>
Sachin Bhandari
  • 524
  • 4
  • 19
0

You can also resolve this problem by editing little bit in Your html code

<div class="parent" id="parent-div">

<!-- Just adding parent div text inside span tag -->

<span>parent</span>

<div class="child">child</div>

</div>

now go to jquery code

 $('.parent span').on('click',function(){

  //only print child text u can do more

  alert($('.child').text());

  //Change color of child

  $('.child').css('color','red');

});