2013-02-20 71 views
1

我有下面粘贴或看到它在jsfiddle崩溃菜单中的代码。问题与停止(真).slideDown()效果基本show()时,是一个jQuery的错误?

问题是,当子菜单处于向上滑动状态时,再次单击该按钮,它会停止但不会向后动画(而不是子菜单跳出,但它们的容器保持其当前高度 - 不跳jQuery 2.0.0.b1)。在Firefox和Chrome中测试的结果相同。

这是一个jQuery bug,或者只是我吗?

更新:我有filed a bug report为jQuery,因为我认为这是一个jQuery的bug。

更新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(); 
}); 

回答

3

.slideDown()不工作的原因是因为元素的显示设置为“block”,并且.slideDown()通常打算在显示为“none”的元素上调用。 在你的else if语句的ul元素上包含.hide()以获得你想要的行为。

li 
    .removeClass("closed inslideup") 
    .addClass("inslidedown") 
    .find("ul") 
    .first() 
    .hide() // <---- 
    .stop(true) 
    .slideDown(); 
+0

哇,这[很好](http://jsfiddle.net/HuCmy/37/)!谢谢。不知何故,我没有看到你的答案,对不起。 – 2013-02-20 17:43:06

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这些元素,是unnecesary JavaScript中,你可以用用CSS做像我一样,其他问题JS的方式是,对于一个微小的时刻出现和消失,因为你必须要等到所有的文档加载到隐藏的那些元素。

+0

代码中没有'.stop()',我认为问题出现在代码中的某处。 – 2013-02-20 02:16:33

+0

是的,没有,但问题并没有停止(),你可以将它添加到我的代码,但我再说一遍,问题不是这样,所以我没有编码该部分 – martriay 2013-02-20 02:30:32

0

基本上你应该检查<ul>下的所有<li>节点是否有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) { 
    ... 
} 
+0

“li”节点与“打开”类是其中具有子菜单的“ul”的父类。因此,只有一个与我想要使用的类相关的li,并且click事件触发了这个实际的'li'元素。 – 2013-02-20 02:19:55

+0

@styu正确。但是,您必须检查其他李的班级,以确保自实施手风琴效果以来,一次只打开一个班级。 – zsong 2013-02-20 02:50:31

+0

对不起,我的错误是,我不想要手风琴,但要崩溃。这个问题只与'.stop()。slideUp()'的奇怪行为有关。 – 2013-02-20 02:53:33

0

第一个问题是由于您的.stop()

据jQuery的文档的使用,

.stop([clearQueue] [,jumpToEnd])

clearQueue 类型:Boolean 布尔值,指示是否要删除排队动画以及。默认为false。

jumpToEnd 类型:Boolean 布尔值,指示是否立即完成当前动画。默认为false。

一般情况下,你想用动画处理时使用.stop(假,真)。

至于你的第二个问题,原因是由于下面的jquery/css。

li.removeClass( “封闭inslideup”)

li.closed> UL {显示:无; }

当您删除了“封闭”类,UI元素的显示将重新设置为默认的“块”,因此即时显示。滑动的动画不会发生,因为元素已经显示(回调仍然执行)。

+0

我不想使用'.stop(false,true)',因为这样它会在'stop()'上跳转。 '.stop(true)'用'slideDown()'可以正常工作,但不能用'slideUp()'。 – 2013-02-20 02:11:46

+0

我了解第二个问题的原因,但不知道如何防止它没有JavaScript(我想菜单元素最初是关闭的)。但是我现在只是重新考虑它,并认为这种方法显然是错误的,所以在用javascript初始化时隐藏它就可以了。将尽快更新问题。 – 2013-02-20 02:25:12

0

现在我正在使用一种解决方法,在滑动动画正在进行时,它完全忽略了单击事件。 刚刚从.on()的第23行选择器过滤参数中删除li.inslideup a, li.inslidedown a选择器(留下其他代码完好无损,以防jQuery得到修复,但它可以被简化)。

解决方法是在jsfiddle

相关问题