2013-02-20 34 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

相關問題