怎么有手风琴式的菜单?

时间:2012-03-28 11:48:06

标签: jquery

我正在创建一个文件夹视图类型的插件,我把我的代码放在jsfiddle ...

http://jsfiddle.net/masnR/1/ 基本上我在尝试手风琴类型......

当我点击Folder2时,folder1应该崩溃,只有folder2应该可见并展开。

我怎样才能继续这个......?

2 个答案:

答案 0 :(得分:1)

可以使用slideUpslideDown进行手风琴动画效果。两者都得到jQuery的支持。但使用jQuery accordion更容易。

答案 1 :(得分:1)

在我给你解决方案之前

我现在可以告诉你,你的HTML结构不太一致先生/太太!

您的顶级节点链接未包含在li中,并且处理方式不同。所有节点都应具有相同的结构,以便于遍历。

我建议您考虑使用看起来像这样的经典设置

<div class='container'>
    <ul>
        <li>
            <a href='#'>Folder 1</a>
            <ul>
                <li>Sub item 1</li>
                <li>Sub item 2</li>
                <li>
                    <a href='#'>Sub Folder 1</a>
                    <ul>
                        <li>Sub item 1</li>
                        <li>Sub item 2</li>
                        <li>Sub item 3</li>
                    </ul>
                </li>
            </ul>
        </li>
        <!-- ... -->
    </ul>
</div>

这更加一致,并且更容易遍历...它也非常美观......;)

您的JavaScript代码效率低下。不要折叠每个li,而是考虑折叠ul。我也很难解读代码试图做的事情,因为我相信每个人都有,这就是为什么你没有得到很多答案。
考虑添加注释或使您的代码“更清晰”以供查看。这是为了每个人的缘故,包括你自己的。


实施例

我已创建this example供您查看。这些菜单非常常见,因此您可以期待许多其他插件具有类似的标记/功能。

它使用与前面提到的相同的HTML结构。

Example |代码

$(document).ready(function () {
    $('.fileview').fileview({
        bAnimate: false //I don't like animations to be honest ;)
    });
});

$.fn.fileview = function(options) {
    var config = {
        sCollapseClass: "collapse",
        sUncollapseClass: "uncollapse",
        sSelectedClass: "selected",
        bCollapseAll: true,
        bCollapseAdjacent: true,
        bStartCollapsed: true,
        bAnimate: true,
        iAnimationTime: 250
    };

    $.extend(config, options);

    //Collapse link & list
    function collapse($link, $list){
        //Remove the uncollapse class and add the collapse class to link and list
        $($link).removeClass(config.sUncollapseClass)
                .addClass(config.sCollapseClass);
        $($list).removeClass(config.sUncollapseClass)
                .addClass(config.sCollapseClass);

        //Animate?
        if(config.bAnimate){
            $list.slideUp(config.iAnimationTime);
        }else{
            $($list).hide();  
        }

        //Collapse nested lists?
        if(config.bCollapseAll){
            $("ul."+config.sUncollapseClass, $list).each(function(){
                collapse($(this).prev(), $(this));
            });
        }
    }

    //Uncollapse link & list
    function uncollapse($link, $list){

        //Remove the collapse class and add the uncollapse class to link and list
        $link.removeClass(config.sCollapseClass)
             .addClass(config.sUncollapseClass);
        $list.removeClass(config.sCollapseClass)
             .addClass(config.sUncollapseClass);

        //Animate?
        if(config.bAnimate){
            $list.slideDown(config.iAnimationTime);
        }else{
            $list.show();
        }

        //Collapse adjacent nodes?
        if(config.bCollapseAdjacent){
            $link.closest("li").siblings("li").each(function(){
                collapse($(this).children(":nth-child(1)"), $(this).children(":nth-child(2)"));
            });
        }  
    }

    //Select node
    function select(link, context){
        if(config.sSelectedClass == "" || $(link).hasClass(config.sSelectedClass)) return;

        $("."+config.sSelectedClass, context).removeClass(config.sSelectedClass);
        $(link).addClass(config.sSelectedClass);
    }

    //Start collapsed?
    if(config.bStartCollapsed === true){
        $("a, ul", $(this).children()).each(function(){
            if(!$(this).hasClass(config.sUncollapseClass))
                $(this).addClass(config.sCollapseClass);
        });
    }else if(config.bStartCollapsed === false){
        $("a, ul", $(this).children()).each(function(){
            if(!$(this).hasClass(config.sCollapseClass))
                $(this).addClass(config.sUncollapseClass);
        });
    }

    //Hide collapse class list nodes
    $("ul."+config.sCollapseClass, this).hide();

    this.each(function(){
        var _self = this;

        //Collapse/Uncollapse for list items that have a ul child
        $("li > ul", this).each(function(){
            var $_this = $(this),
                $link = $(this).siblings("a");

            $link.click(function(){
                if($_this.hasClass(config.sCollapseClass)){
                    uncollapse($link, $_this);
                }else{
                    collapse($link, $_this);
                }
            });
        });

        //Select event
        $("a", this).click(function(){
            select(this, _self);
        });

    });    
};

解决方案

您的代码似乎存在其他问题,但这是我使用当前标记执行此操作的方法。

Example |代码

function showElement(element){
    element.addClass(config.collapseElementClass);
    element.removeClass(config.expandElementClass);
    element['siblings']()[displayEffectShow]();
    element.html(htmlCollapse);

    //Select all the li siblings
    var $siblings = element.closest("li").siblings("li");

    //Check if there were no siblings, which would indicate that we're at the top node
    if($siblings.length == 0)
        $siblings = element.closest("ul").siblings("ul");

    //Hide all the siblings
    $siblings.each(function(){
        hideElement($("a", this));
    });
}