使用嵌套层次结构实现可折叠

时间:2013-11-20 22:32:17

标签: javascript jquery html twitter-bootstrap twitter-bootstrap-3

我试图模仿手风琴的任务slideToggle和面板与bootstrap 3作为框架。但是,到目前为止,我的方法并没有发挥作用。我的问题是,无法打开任何面板,但是第一个面板,如果在第一个外面板内部单击内部panel-heading,则第一个面板完全隐藏。我有一个面板组,里面有几个面板,在这些面板内有另一个面板组,里面有几个面板。每当打开一个面板(切换身体)时,我需要隐藏其他面板,如果它们还没有。

我创建了一个JSfiddle:http://jsfiddle.net/Lk29k/

JS:

$(document).ready(function () {

    //when a heading is clicked, a toggle is preformed 
    //and all other toggles are hidden.

    //outside panel
    $('#panelHeadingOuter').click(function (event) {
        event.preventDefault();
        var sliderContent = $(this).next('#panelBodyOuter');
        $('#panelBodyOuter').not(sliderContent).hide();
        sliderContent.slideToggle("fast");

        $('#panelBodyOuter').click(function () {
            $(this).parent().hide();
        });
    });

    //inside panel
    $('#panelHeadingInner').click(function (event) {
        event.preventDefault();
        var sliderContent2 = $(this).next('#panelBodyInner');
        $('#panelBodyInner').not(sliderContent2).hide();
        sliderContent2.slideToggle("fast");
        $('#panelBodyInner').click(function () {
            $(this).parent().hide();
        });
    });
});

1 个答案:

答案 0 :(得分:3)

您需要阻止事件传播到其父级。在这里,当你单击子进程时,它会执行自己的处理程序并单击事件冒泡到其父进程并执行自己的单击事件,从而导致折叠行为(因为它已经打开)。

尝试

   $('#panelHeadingInner').click(function (event) {
      event.stopPropagation();
      ....

当你知道元素已经存在时,复制html中的id并将事件附加到另一个事件中也是一个坏主意。

如果您将ID更改为类并修改JS代码以使其更简单,您可以实现此目的:

 $(document).ready(function () {
    var $panelOuter = $('.panelBodyOuter'), $panelInner = $('.panelBodyInner');
    $('.panelHeadingOuter').click(function (event) {
        var sliderContent = $(this).next('.panelBodyOuter');
        $panelOuter.not(sliderContent.slideToggle("fast", changeInnerState)).find('.panel-body:visible').addBack().slideUp();
        if(sliderContent.is(':hidden')){
            sliderContent.find('.panel-body:visible').slideUp();
        }
    });
    $('.panelHeadingInner').click(function (event) {
        event.stopPropagation();
        var sliderContent = $(this).next('.panelBodyInner');
        $panelInner.not(sliderContent.slideToggle("fast", changeInnerState)).find('.panel-body:visible').addBack().slideUp();;

    });
});
function changeInnerState(){
  var $this = $(this);
  if($this.is(':hidden'))
     $this.find('.panel-body').slideUp();
}

<强> Demo

<强>更新

为了更灵活,只需在html中将您的班级名称panelBodyOuter/Inner重命名为panelBody,将panelHeaderOuter/Inner重命名为panelHeader,然后您就可以灵活地添加它只需一次事件登记即可尽可能多地嵌套。

JS:

$(document).ready(function () {
    $('.panelHeading').click(function (e) {
        e.stopPropagation();
        var $sliderContent = $(this).next('.panelBody'),
            $panelBody = $(this).closest('.panel-group').find('.panel-body');
        $panelBody.not($sliderContent.slideToggle("fast", changeInnerState)).find('.panel-body:visible').addBack().slideUp();
    });

});

function changeInnerState() {
    var $this = $(this);
    if ($this.is(':hidden')) $this.find('.panel-body').slideUp();
}

HTML:

      <div class='panel-group'>
        <div class='panel panel-primary'>
            <div class='panel-heading panelHeading'>
                 <h4 class='panel-title'>Outer1</h4>

            </div>
            <div class='panel-body panelBody' style='display:none;'>
                <div class='panel-group'>
                    <div class='panel panel-primary'>
                        <div class='panel-heading panelHeading'>
                             <h4 class='panel-title'>Inner1</h4>

                        </div>
                        <div class='panel-body panelBody' style='display:none;'>
                            <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit.</p>
                        </div>
                    </div>
                    <div class='panel panel-primary'>
                        <div class='panel-heading panelHeading'>
                             <h4 class='panel-title'>Inner2</h4>

                        </div>
                        <div class='panel-body panelBody' style='display:none;'>
                            <p>Pellentesque est odio, hendrerit vitae nisi eget, bibendum porttitor tellus. Aliquam vel luctus mauris.</p>
                        </div>
                    </div>
                </div>
            </div>
        </div>
        <!-- panel -->
        <div class='panel panel-primary'>
            <div class='panel-heading panelHeading'>
                 <h4 class='panel-title'>Outer2</h4>

            </div>
            <div class='panel-body panelBody' style='display:none;'>
                <div class='panel-group'>
                    <div class='panel panel-primary'>
                        <div class='panel-heading panelHeading'>
                             <h4 class='panel-title'>Inner3</h4>

                        </div>
                        <div class='panel-body panelBody' style='display:none;'>
                            <p>Duis vitae viverra dui.</p>
                        </div>
                    </div>
                    <div class='panel panel-primary'>
                        <div class='panel-heading panelHeading'>
                             <h4 class='panel-title'>Inner4</h4>

                        </div>
                        <div class='panel-body panelBody' style='display:none;'>
                            <p>Maecenas magna nisi, consequat quis felis sit amet, placerat blandit erat.</p>
                        </div>
                    </div>
                </div>
            </div>
        </div>
    </div>

<强> Demo