2012-10-25 173 views
0

我正嘗試創建一個具有很酷滑動/淡入效果的多層菜單。現在,它在我的第一次點擊上工作,但之後失敗。jQuery滑動菜單難點

HTML

<ul id="menu"> 
<li> 
    Development 
    <div> 
     <ul> 
      <li>Sub 1</li> 
      <li>Sub 2</li> 
     </ul> 
    </div> 
</li> 
<li> 
    Story 
    <div> 
     <ul> 
      <li>Sub 1</li> 
      <li>Sub 2</li> 
     </ul> 
    </div> 
</li> 
<li> 
    News 
    <div> 
     <ul> 
      <li>Sub 1</li> 
      <li>Sub 2</li> 
     </ul> 
    </div> 
</li> 
</ul>​ 

的JavaScript

var observeClicks = function(){ 
    var lis = $('#menu').children('li'); 

    lis.click(function(){ 
     lis.unbind(); 
     var $this = $(this); 
     var $div = $($this.children('div')[0]); 
     var $ul = $($div.children('ul')[0]); 

     var clone = $ul.clone(true, true) 
      .css({visibility: 'hidden', display: 'block'}); 
     clone.attr('style', clone.attr('style').replace('block', 'block !important')) 
      .insertAfter($ul); 

     setTimeout(function(){ 
      $ul.css({height: clone.css('height')}); 
      $div.css({height: clone.css('height')}); 
      clone.remove(); 
     }, 0); 

     if(!lis.hasClass('current')){ 
      $this.addClass('current'); 
      $div.slideDown(350, function(){ 
       $ul.fadeIn(350); 
       observeClicks(); 
      }); 
     }else{ 
      if(!$this.hasClass('current')){ 
       $current = $($('.current')[0]); 
       $cdiv = $($current.children('div')[0]); 
       $cul = $($cdiv.children('ul')[0]); 

       $cdiv.css({height: $cul.css('height')}); 

       $this.addClass('current'); 
       $current.removeClass('current'); 
       $cul.fadeOut(350, function(){ 
        $cdiv.slideUp(350, function(){ 
         $div.slideDown(350, function(){ 
          $ul.fadeIn(350); 
          observeClicks(); 
         }); 
        }); 
       }); 
      }else{ 
       observeClicks(); 
      } 
     } 
    }); 
} 
observeClicks(); 

CSS

#menu { 
    cursor: pointer; 
    width: 150px; 
} 

#menu div { 
    display: none; 
    width: 100%; 
} 

#menu li ul { 
    display: none; 
    margin-left: 25px; 
} 

,我R中的第一個有趣的問題一個進入是,而不是滑動,我的菜單只是「彈出」。這是因爲該div沒有佔用空間,直到其中的元素顯示。所以我通過給它一個固定的區域克服了這個問題。 (寬度在CSS中設置,高度在JavaScript中設置)。我認爲這是問題出在哪裏,我插入一個虛擬元素,讀取它的高度,將其分配給div,然後刪除元素。這很粗略我知道,但我找不到更好的方法。

無論如何,當我第一次點擊一個菜單項,它完美的作品。但只要我嘗試第二次點擊,看起來高度不會爲div設置,並且沒有滑動效果。 Check it out here.

您可能還注意到,這不是我想勾搭.stop()的動畫,我只是解除綁定單擊處理程序,然後在所有的動畫重新綁定他們已經完成。這是故意的,在添加之前,我有這個問題。如果有人可以告訴我要修復什麼,這將非常感激。

+0

我前一陣子做了這個。如果你想爲類似的菜單減少代碼可能會有用:http://jsfiddle.net/aCaEG/ – Johan

回答

1

它接縫的問題是在克隆高度一塊碼。我不知道爲什麼它僅與第一個元素的工作點擊,但是你可以通過簡單地在CSS中設置這個元素的高度解決它:

#menu div { 
    display: none; 
    width: 100%; 
    height: 40px; 
} 

#menu li ul { 
    display: none; 
    margin-left: 25px; 
    height: 40px; 
} 

並刪除克隆JS代碼和ASIGN高度,它在jsfiddle中看起來不錯:http://jsfiddle.net/j7EHu/

+0

我想我可以這樣做,但我希望找到一種自動獲取高度的方式,所以當我從菜單中添加/刪除東西時,我不必擔心一遍又一遍地調整CSS。 – Aust

+0

你可以用一個簡單的lineheight-depends操作爲組件指定一個高度:$ div.css({height:$ ul.children().lenght * $ ul.css('lineHeight')});你不需要克隆和定時器,這更復雜。 –

0

請使用,而不是你的代碼:

#menu { 
    cursor: pointer; 
    width: 150px; 
} 

#menu div { 
    display: none; 
    width: 100%; 
} 

#menu li ul { 
    margin-left: 25px; 
} 

JS

$("#menu > li").click(function(){ 
     $('#menu .active').slideUp(350).removeClass('active'); 
     $(this).find('div').slideDown(350,function() { 
      $(this).addClass('active'); 
     }); 
}); 

這裏對一個演示:http://jsfiddle.net/yL944/12/

+0

我試圖得到滑落的效果,然後淡入,而不是滑下來。 – Aust