I have the code for a collapse menu pasted below or see it on jsfiddle.
The issue is when the submenu is in the sliding up state, and it is clicked again, it stops but is not being animated backwards (instead the submenus are jumping out but their container is keeping its current height – no jump with jQuery 2.0.0.b1). Tested in Firefox and Chrome with the same result.
Is this a jQuery bug, or just me?
Update: I have filed a bug report for jQuery, because I think that this is a jQuery bug.
Update 2: See Brad M’s accepted answer with the explanation of this behavior (but I still think that this is an issue with jQuery which needs to be solved internally).
HTML
<ul>
<li><a href="#">Menu1</a></li>
<li class="opened"><a href="#">Submenus 1</a>
<ul class="submenu">
<li><a href="#">submenu1-1</a></li>
<li><a href="#">submenu1-2</a></li>
</ul></li>
<li class="closed"><a href="#">Submenus 2</a>
<ul class="submenu">
<li><a href="#">submenu2-1</a></li>
<li><a href="#">submenu2-2</a></li>
</ul></li>
<li><a href="#">Menu4</a>
</li>
</ul>
Javascript
var initMenu = function() {
$("li.closed > ul.submenu").css("display", "none");
var toggleMenu = function(li) {
if (li.hasClass("opened") || li.hasClass("inslidedown")) {
li.removeClass("opened inslidedown").addClass("inslideup").find("ul").first().stop(true).slideUp({
duration: 1000,
complete: function() {
li.addClass("closed").removeClass("inslideup");
}
});
}
else if (li.hasClass("closed") || li.hasClass("inslideup")) {
li.removeClass("closed inslideup").addClass("inslidedown").find("ul").first().stop(true).slideDown({
duration: 1000,
complete: function() {
li.addClass("opened").removeClass("inslidedown");
}
});
}
};
$("ul").on("click", "li.opened a, li.closed a, li.inslideup a, li.inslidedown a", function(e) {
e.preventDefault();
toggleMenu($(this).closest("li"));
});
};
$(document).ready(function() {
initMenu();
});
The reason
.slideDown()isn’t working is because the element’s display is set to “block” and.slideDown()is generally intended to be called on elements with display “none”.Include
.hide()on the ul element in your else if statement to get the behavior you desire.