Reputation: 77
I am working through an issue where I have a menu that is mutli levels deep. I am trying to get it so that if a first level element is clicked (add class .ubermenu-active
) it will look for any other first level element with that class and remove it.
$('.ubermenu-item-level-0 span').on('click',function() {
var target = $('.ubermenu-item-level-0');
$('.ubermenu li.ubermenu-item-level-0').removeClass('ubermenu-active');
target.parents('.ubermenu li.ubermenu-item-level-0').toggleClass('ubermenu-active');
});
HTML (mock):
<ul class="ubermenu">
<li class="ubermenu-item-level-0">
<a class="ubermenu-target">
<span class="ubermenu-target-title">Level 1</span>
</a>
<ul class="ubermenu-submenu">
<li class="ubermenu-item-level-1">
<a class="ubermenu-target">
<span class="ubermenu-target-title">Level 2</span>
</a>
</li>
<li class="ubermenu-item-level-1">
<a class="ubermenu-target">
<span class="ubermenu-target-title">Level 2</span>
</a>
<ul class="ubermenu-submenu">
<li class="ubermenu-item-level-2">
<a class="ubermenu-target">
<span class="ubermenu-target-title">Level 3</span>
</a>
</li>
</ul>
</li>
</ul>
<li class="ubermenu-item-level-0">
<a class="ubermenu-target">
<span class="ubermenu-target-title">Level 1</span>
</a>
</li>
</li>
</ul>
Right now if any of the sub elements are clicked the parent closes
Upvotes: 0
Views: 293
Reputation: 7950
So, your sample HTML isn't what I expected to see . . . specifically, your second <li class="ubermenu-item-level-0" . . .
element is currently showing as a child under the first one, while your description makes it sound like they should be siblings.
For the sake of the solution I'm going to assume that those two li
s are supposed to be siblings of each other and that somehow the code got mixed up. :)
So, here's how I would handle it . . .
var sFirstLevelMenuClass = ".ubermenu-item-level-0";
var sActiveMenuClass = "ubermenu-active";
var $firstLevelMenuOptions = $(".ubermenu").find(sFirstLevelMenuClass);
$firstLevelMenuOptions.children("a").children("span").on("click", function() {
$firstLevelMenuOptions.removeClass(sActiveMenuClass);
$(this).closest(sFirstLevelMenuClass).addClass(sActiveMenuClass);
});
Basically, I've simplified your logic and fixed one small issue that you had in your jQuery code.
Detailed Explanation
The issue was that when you used $('.ubermenu-item-level-0 span')
as your selector for your change event. That translates to "any span
element that is a descendant of a ubermenu-item-level-0
element". So, in addition to the spans that are directly under the ubermenu-item-level-0
list items, it was also picking up the ones under the ubermenu-item-level-1
and ubermenu-item-level-2
elements, since they are also descendants.
So, I changed your selector to $firstLevelMenuOptions.children("a").children("span")
which translates to "all span
s, that are direct children of an a
, that is the direct child of an ubermenu-item-level-0
element" (Note: $firstLevelMenuOptions
is set to equal $(".ubermenu").find(".ubermenu-active");
through the logic earlier in the code). This stops the selector from picking up the lower level spans
.
Outside of that and trimming down some of your selectors to be more efficient, the only other thing that I changed was the flow of how the ubermenu-active
class is manipulated. In my solution, there are two steps:
ubermenu-active
from ALL ubermenu-item-level-0
elementsubermenu-active
to the closest ubermenu-item-level-0
element to the span
that was clicked (i.e., $(this)
)That basically resets the list and then reselects the appropriate menu item to me active.
Upvotes: 0
Reputation: 1705
Currently your target
var is selecting all elements with class .ubermenu-item-level-0
, so when you toggle the class you're toggling all parent elements. Your target var should be something relative to the element clicked, like var target = $(this).closest('.ubermenu-item-level-0');
Upvotes: 1
Reputation: 694
Without seeing the full HTML, I was going to suggest trying this:
$('.ubermenu-item-level-0 span').on('click',function(e) {
e.stopPropagation();
var target = $('.ubermenu-item-level-0');
$('.ubermenu li.ubermenu-item-level-0').removeClass('ubermenu-active');
target.parents('.ubermenu li.ubermenu-item-level-0').toggleClass('ubermenu-active');
});
Upvotes: 0