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,然后删除该元素。我知道这很粗略,但我找不到更好的方法。

无论如何,当我第一次单击菜单项时,它可以完美运行。但是当我尝试第二次点击时,似乎没有为div设置高度,并且没有滑动效果。在这里查看。

您可能还注意到,我没有尝试.stop()处理动画,而是取消绑定点击处理程序,然后在所有动画完成后重新绑定它们。这是经过深思熟虑的,在添加之前我遇到了这个问题。如果有人能告诉我要解决什么问题,将不胜感激。

4

2 回答 2

1

似乎问题出在克隆高度的代码中。我不确定为什么它只适用于单击的第一个元素,但您可以通过简单地在 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 回答