Reputation: 1053
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
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
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 thanul.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