2012-10-25 3 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>​ 

자바 스크립트

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를 사용하여 구성 요소에 높이를 지정할 수 있습니다. $ 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'); 
     }); 
}); 

는 데모를 SI : http://jsfiddle.net/yL944/12/ 그것은 문제의 복제 높이 부분에 솔기

+0

아래로 미끄러지는 효과를 얻으려는 중입니다. – Aust