I have a simple nav structure for a nav that has toggles to open and close sub-menus. However, when I click on a nested menu the toggle works, but also closes the parent sub-menu. How can I set it so that the parent doesn't close on the click of the nested menu?
jQuery(document).ready(function($) {
//Toggle sub-menus
$('#menu .has-children').on('click', function(event) {
event.preventDefault();
$(this).children('.sub-menu').slideToggle(500);
});
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<ul id="menu">
<li>item 1</li>
<li class="has-children">item 2
<ul class="sub-menu">
<li>sub-item 1</li>
</ul>
</li>
<li class="has-children">item 3
<ul class="sub-menu">
<li>sub-item 1</li>
<li class="has-children">sub-item 2
<ul class="sub-menu">
<li>sub-sub-item 1</li>
</ul>
</li>
</ul>
</li>
</ul>
<iframe name="sif1" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>
CodePudding user response:
event.preventDefault();
doesn't stop the event from traveling up the tree, you need to use event.stopPropagation();
to stop the click from also triggering the click event listeners on parent elements.
(You could also add this to li
inside sub menus without .has-children
, to prevent them from closing parent menus, though that's unnecessary if those nav items link to other pages)
jQuery(document).ready(function($) {
//Toggle sub-menus
$('#menu .has-children').on('click', function(event) {
event.preventDefault();
event.stopPropagation();
$(this).children('.sub-menu').slideToggle(500);
});
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<ul id="menu">
<li>item 1</li>
<li class="has-children">item 2
<ul class="sub-menu">
<li>sub-item 1</li>
</ul>
</li>
<li class="has-children">item 3
<ul class="sub-menu">
<li>sub-item 1</li>
<li class="has-children">sub-item 2
<ul class="sub-menu">
<li>sub-sub-item 1</li>
</ul>
</li>
</ul>
</li>
</ul>
<iframe name="sif2" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>