Reputation: 5951
I've been trying to get a simple vertical navigation to display a list item's children on click.
However when you then click any of those nested, children list items you are in essence 'clicking' the parent list item again. Which triggers my click function to remove '.active' and closes the parent list item right before the user is redirected to their chosen page. This looks bad and is totally annoying.
Any advice on how to get a click function to not affect the children list items?
$('#sidebar > li.parent').click(function(){
if($(this).hasClass('active')){
$(this).removeClass('active');
}else{
$(this).addClass('active');
}
});
HTML
<aside id="tertiary" class="tertiary">
<ul id="sidebar" class="sidebar">
<li class="active"><a href="/">Portal</a></li>
<li><a href="ecards.html">Start Here</a></li>
<li><a href="ecards.html">Cards</a></li>
<li class="parent"><a href="programs.html">Programs</a>
<ul>
<li><a href="#">LOS</a></li>
<li><a href="#">Safety</a></li>
<li><a href="#">Retirement</a></li>
<li><a href="#">Wellness</a></li>
<li><a href="#">Investors</a></li>
</ul>
</li>
<li><a href="#">Marketplace</a></li>
<li><a href="#">Reporting</a></li>
</ul>
</aside>
Upvotes: 1
Views: 126
Reputation: 8484
Before you stop propagation of events, take some time to spin up on why you shouldn't do so.
From css-tricks.com, "The Dangers of Stopping Event Propagation", very briefly:
"Modifying a single, fleeting event might seem harmless at first, but it comes with risks. When you alter the behavior that people expect and that other code depends on, you're going to have bugs. It's just a matter of time."
"A much better solution is to have a single event handler whose logic is fully encapsulated and whose sole responsibility is to determine whether or not the menu should be hidden for the given event."
With that being said, you could do something like
$('#sidebar').on('click', function( e ) {
var $target = $(e.target).closest('li');
if ( $target.hasClass('parent') ) {
$target.toggleClass('active');
}
});
Working example: http://jsfiddle.net/g6a496Lf/1/
Upvotes: 1
Reputation: 30330
You could add a click handler for the child elements that uses stopPropagation
to prevent the click event bubbling to parent elements:
$('#sidebar > li li').click(function(e){
e.stopPropagation();
});
Further reading: MDN docs for Event
.
Upvotes: 2
Reputation: 93601
You would need to stop propagation in the children... not the parent
http://jsfiddle.net/TrueBlueAussie/g6a496Lf/
$('#sidebar > li.parent').click(function (e) {
e.preventDefault();
$(this).toggleClass('active');
}).find("ul li").click(function(e){
e.stopPropagation();
});
The e.preventDefault()
is just there to stop the link clicking on the parent in the example. e.stopPropagation()
stops the child click bubbling up the DOM.
I chained the two handlers together, so that you did not need a separate selector like this:
$('#sidebar > li.parent ul li").click(function(e){
e.stopPropagation();
});
Upvotes: 4