Joe Consterdine
Joe Consterdine

Reputation: 1053

JQuery Event Bubbling Issue

JSFiddle: https://jsfiddle.net/3v2qav58/

having an issue with a dropdown menu.

The issue my sub category list item has a ul/dropdown inside it, so I've grabbed the list item and used '.find()' to get the dropdown and then try slideToggle it.

The issue is I have 3 list items and when I click on the other ones they also open and close the other list items for e.g There is only the dropdown on the first list item but if you click the 2nd/3rd they also toggle.

I think it's to do with event bubbling because I thought '.find()' only traversed down and not up?

Could some explain why this is happening who the event bubbling occurs and how to resolve it?

Cheers

HTML

<ul class="dropdown">
  <li class="dropdown-item">
    <a href="">Cat 1</a>
    <ul class="sub-dropdown">
      <li class="dropdown-sub-item">
        <a href="#">Sub Cat 1</a>
        <ul class="sub-dropdown-child">
          <li class="sub-dropdown-child-item"><a href="#">Sub Cat Child 1</a></li>
          <li class="sub-dropdown-child-item"><a href="#">Sub Cat Child 2</a></li>
          <li class="sub-dropdown-child-item"><a href="#">Sub Cat Child 3</a></li>
        </ul>
      </li>

CSS

.sub-dropdown,
.sub-dropdown-child {
  display: none;
}

JQuery

var dropdownItem = $(".dropdown-item");
var dropdownSubItem = $(".sub-dropdown");
var DropdownSubItem = $(".dropdown-sub-item");
var subDropdownChild = $(".sub-dropdown-child");

// Open
dropdownItem.on("click", function(e) {
  e.preventDefault();
  dropdownSubItem.show();

  // Open sub cat
  dropdownSubItem.on("click", function(e) {
    e.stopPropagation();
    $(this).find(subDropdownChild).slideToggle();
  });
});

Upvotes: 0

Views: 61

Answers (2)

Arg0n
Arg0n

Reputation: 8423

Change your JS to the following:

$(".dropdown-item").on("click", function(e) {
  e.preventDefault();
  $(this).find(".sub-dropdown").toggle();
});
$(".sub-dropdown").on("click", function(e) {
  e.stopPropagation();
  $(this).find(".sub-dropdown-child").slideToggle();
});
$(".sub-dropdown-child").on("click", function(e) {
  e.stopPropagation();
});
.sub-dropdown,
.sub-dropdown-child {
  display: none;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul class="dropdown">
  <li class="dropdown-item">
    <a href="">Cat 1</a>
    <ul class="sub-dropdown">
      <li class="dropdown-sub-item">
        <a href="#">Sub Cat 1</a>
        <ul class="sub-dropdown-child">
          <li class="sub-dropdown-child-item"><a href="#">Sub Cat Child 1</a></li>
          <li class="sub-dropdown-child-item"><a href="#">Sub Cat Child 2</a></li>
          <li class="sub-dropdown-child-item"><a href="#">Sub Cat Child 3</a></li>
        </ul>
      </li>
    </ul>
  </li>
  <li class="dropdown-item">
    <a href="">Cat 2</a>
    <ul class="sub-dropdown">
      <li class="dropdown-sub-item">
        <a href="#">Sub Cat 2</a>
        <ul class="sub-dropdown-child">
          <li class="sub-dropdown-child-item"><a href="#">Sub Cat Child 1</a></li>
          <li class="sub-dropdown-child-item"><a href="#">Sub Cat Child 2</a></li>
          <li class="sub-dropdown-child-item"><a href="#">Sub Cat Child 3</a></li>
        </ul>
      </li>
    </ul>
  </li>
</ul>

The problem with your code is that you where showing ALL sub-items, and not just the sub-items of the clicked one:

dropdownSubItem.show(); //This shows all sub-items

I replaced that with this:

$(this).find(".sub-dropdown").toggle();

Also, you did the event-binding multiple times for sub-items when clicking on a root-item:

dropdownItem.on("click", function(e) {
  ...
  dropdownSubItem.on("click", function(e) {
    ...
  });
  ...
});

Which results in event-binding on each click.

Upvotes: 1

Guruprasad J Rao
Guruprasad J Rao

Reputation: 29683

2 things:

  • Keep click event for sub item outside of first event, separately.
  • You must have attached your click event to li.DropdownSubItem rather than ul.dropdownSubItem.

Here's the updated code and Fiddle

// Open
dropdownItem.on("click", function(e) {
  e.preventDefault();
  dropdownSubItem.show();
});

// Open sub cat
DropdownSubItem.on("click", function(e) {
  $(this).find(subDropdownChild).slideToggle();
  e.stopImmediatePropagation();
});

Upvotes: 0

Related Questions