3

Hi I have child ul and parent li which is being targeted by jquery which toggles class "shown" on click event within it. The problem I face is that for some reason when I click child ul li elements it also triggers that event. How to prevent that?

Here is my code.

<script>
    $(document).ready(function() {
        $('.dropdown').click(function(e) {
            e.stopPropagation();
            $(this).toggleClass('shown');
            e.preventDefault();
        })
    })
</script>


<li class="dropdown"><a title="Installation" href="#">Installation <span class="caret"></span></a>
    <ul role="menu" class="dropdown-menu">
        <li>
            <a title="Wood Floor Installation" href="">Wood Floor Installation</a></li>
        <li>
            <a title="Sub Floor Preparation" href="">Sub Floor Preparation</a></li>
        <li>
            <a title="Type of your subfloor" href="">Type of your subfloor</a></li>
        <li>
            <a title="Wood Floor Fitting Method" href="">Wood Floor Fitting Method</a>
        </li>
    </ul>
</li>
Andrius Solopovas
  • 967
  • 11
  • 41

5 Answers5

7

You're specifying that you want everything in dropdown to trigger the event. If you only want the top level A, it looks more like this:

jQuery(document).ready(function($) {
   $('.dropdown>a').click(function(e) {
     $(this).parent().toggleClass('shown');
     e.preventDefault();
   })
})
John Green
  • 13,241
  • 3
  • 29
  • 51
  • Frankly, I have no idea what you're asking. Which element is supposed to get its class toggled? – John Green Apr 16 '15 at 13:02
  • Yes. The target is .dropdown, subsetted by direct children of .dropdown. (which, in the example you provided has no further children). It then traverses up the DOM tree to its parent, and toggles a class there. It will not ever select child>ul>li>a Unless the child LI also contains the class 'dropdown'. – John Green Apr 16 '15 at 13:11
  • Yes, which is exactly the code I've provided. I expect that you've not implemented it correctly, and can't tell me what is borked. In fact, the only solution that is really close to what you want is mine. StopPropagation and preventDefault are fine, aren't going to do much for you here... the issue is an addressing one. – John Green Apr 16 '15 at 13:34
  • Sorry man I am just being stupid here it all works. Thank you very much. – Andrius Solopovas Apr 16 '15 at 13:59
2

Use e.stopPropagation() where you dont want the click to bubble

Kushal
  • 1,360
  • 6
  • 16
2

What you're experiencing is called event bubbling. Events triggered on elements deeper in the hierarchy will "bubble" up towards the root of the DOM tree, hence the parent <li> element receives click events instantiated by the child elements.

The easiest way to fix this is to check which element triggered the original event by checking event.target:

<script>
  jQuery(document).ready(function($) {
     $('.dropdown').click(function(e) {
       if (!$(e.target).is('.dropdown-toggle'))
        return;

       $(this).toggleClass('shown');
       e.preventDefault();
     })
  })
</script>


<li class="dropdown"><a title="Installation" href="#" data-toggle="dropdown" class="dropdown-toggle">Installation <span class="caret"></span></a>
  <ul role="menu" class=" dropdown-menu">
      <li>
          <a title="Wood Floor Installation" href="">Wood Floor Installation</a></li>
      <li>
          <a title="Sub Floor Preparation" href="">Sub Floor Preparation</a></li>
      <li>
          <a title="Type of your subfloor" href="">Type of your subfloor</a></li>
      <li>
          <a title="Wood Floor Fitting Method" href="">Wood Floor Fitting Method</a>
      </li>
  </ul>
</li>
Erwin
  • 178
  • 7
1

Try stopImmediatePropagation() like this:

$(document).on('click', '#child_element', function(event) {
   event.stopImmediatePropagation();
})
kapantzak
  • 11,610
  • 4
  • 39
  • 61
-1

You can use target property. just use this code in child element. target="_parent"

Thanks, Hayat S.

Hayat Sama
  • 287
  • 2
  • 10