我有下面粘贴的折叠菜单的代码,或者在jsfiddle上看到它。
问题是当子菜单处于向上滑动状态,并且再次单击它时,它会停止但不会向后动画(相反,子菜单会跳出但是它们的容器保持其当前高度 - 不会跳转到jQuery 2.0.0.b1)。在Firefox和Chrome中测试结果相同。
这是一个jQuery错误,还是只是我?
更新:jQuery我有filed a bug report,因为我认为这是一个jQuery错误。
更新2 :请参阅Brad M接受的答案并解释此行为(但我仍然认为这是jQuery的一个问题,需要在内部解决)。
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();
});
答案 0 :(得分:3)
.slideDown()
无效的原因是因为元素的显示设置为“阻止”,而.slideDown()
通常用于在显示“无”的元素上调用。
在else if语句的ul元素中包含.hide()
以获得所需的行为。
li
.removeClass("closed inslideup")
.addClass("inslidedown")
.find("ul")
.first()
.hide() // <----
.stop(true)
.slideDown();
答案 1 :(得分:0)
这是我的版本:http://jsfiddle.net/RF3xK/4/
使用Javascript:
$(document).ready(function() {
rotator($('#quotes .textItem:first'));
function rotator(elem) {
elem.slideDown(800, function(){
var me = $(this),
next = me.next(),
prev = me.prev();
if (!next.length) {
next = $('.textItem').first();
next.insertAfter(me);
}
rotator(next);
}).delay(800).slideUp(800);
}
});
CSS:
#quotes { background: #eee;}
#quotes .textItem { display: none; }
请注意,我将.hide()替换为document.ready事件上的那些元素,是不必要的javascript,你可以像我一样用css做,js方式的另一个问题是,在一瞬间出现和消失,因为你必须等到加载所有文档才能隐藏这些元素。
答案 2 :(得分:0)
基本上你应该检查<li>
下的所有<ul>
节点是否有css类说关闭或打开,你可以使用jQuery选择器来实现这一点。
这是一种快速而肮脏的修复方法,您绝对可以将其重新考虑为更好的逻辑。
if ($('li[class~="opened"]').length > 0 || $('li[class~="inslidedown"]').length > 0) {
...
}
else if ($('li[class~="closed"]').length > 0 || $('li[class~="inslideup"]').length > 0) {
...
}
答案 3 :(得分:0)
第一个问题是由于您使用了.stop()
根据jquery文档,
.stop([clearQueue] [,jumpToEnd])
clearQueue 类型:布尔值 一个布尔值,指示是否也删除排队的动画。默认为false。
jumpToEnd 类型:布尔值 一个布尔值,指示是否立即完成当前动画。默认为false。
通常,您希望在处理动画时使用.stop(false,true)。
至于你的第二个问题,原因是由于以下jquery / css。
li.removeClass(“关闭inslideup”)
li.closed&gt; ul {display:none; }
当您删除“已关闭”类时,ul元素的显示将被设置回默认的“块”,因此它会立即显示。滑动动画不会发生,因为元素已经显示(尽管回调仍在执行)。
答案 4 :(得分:0)
目前我正在使用一种解决方法,在滑动动画进行过程中忽略了click事件。
刚从第23行的li.inslideup a, li.inslidedown a
选择器过滤参数中删除了.on()
选择器(如果jQuery得到修复,其他代码保持不变,但可以简化)。
解决方法位于jsfiddle。