0

クールなスライド/フェードイン効果を持つ多層メニューを作成しようとしています。今のところ、最初のクリックでは機能しますが、その後は失敗します。

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;
}

私が遭遇した最初の興味深い問題は、メニューがスライドするのではなく、「ポップ」することでした。これは、div 内の要素が表示されるまでスペースを占有しなかったためです。そこで、固定領域を与えることでそれを克服しました。(幅は CSS で設定し、高さは JavaScript で設定します)。ここに問題があると思います。ダミー要素を挿入し、その高さを読み取り、それを div に割り当ててから、要素を削除します。私が知っているのは大ざっぱですが、より良い方法を見つけることができませんでした。

とにかく、メニュー項目を最初にクリックすると、完全に機能します。しかし、2回目のクリックを試みるとすぐに、divの高さが設定されていないようで、スライド効果はありません. ここで確認してください。

.stop()また、アニメーションをいじろうとする代わりに、クリック ハンドラーのバインドを解除し、すべてのアニメーションが終了した後に再度バインドしていることに気付くかもしれません。それは意図的なものであり、それを追加する前にこの問題がありました。誰かが何を修正すべきかを教えてくれれば、それは大歓迎です。

4

2 に答える 2

1

問題はコードの clone-height 部分にあると思われます。クリックされた最初の要素でのみ機能する理由はわかりませんが、css でこの要素の高さを設定するだけで修正できます。

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

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

高さを複製して割り当てる js コードを削除すると、jsfiddle で問題ないように見えます: http://jsfiddle.net/j7EHu/

于 2012-10-25T07:59:36.787 に答える
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/

于 2012-10-25T07:59:28.990 に答える