Bootstrap 3折叠手风琴:折叠所有作品,但在保持数据父级的同时不能全部展开

Posted

技术标签:

【中文标题】Bootstrap 3折叠手风琴:折叠所有作品,但在保持数据父级的同时不能全部展开【英文标题】:Bootstrap 3 collapse accordion: collapse all works but then cannot expand all while maintaining data-parent 【发布时间】:2013-12-19 07:08:48 【问题描述】:

我正在使用 Bootstrap 3 并尝试设置以下手风琴/折叠结构:

    Onload:组中的每个手风琴面板都完全折叠,并且按记录/预期运行。

    按钮点击:每个手风琴面板都会展开,点击切换按钮无效(包括 URL 锚点效果)。

    再点击一次按钮:所有面板返回onload状态;全部折叠并正常点击。

我已进入第 2 步,但是当我在第 3 步再次单击该按钮时,它没有任何效果。在 Chrome 开发工具中或通过我的本地 JSHint 运行代码时,我也没有看到任何控制台错误报告。

我希望每次单击按钮时都可以重复此循环。

我已经在http://bootply.com/98140 和http://jsfiddle.net/A9vCx/ 设置了我的代码

我很想知道我做错了什么,我很感激建议。谢谢!

我的 html

<button class="collapse-init">Click to disable accordion behavior</button>
<br><br>
<div class="panel-group" id="accordion">
  <div class="panel panel-default">
    <div class="panel-heading">
      <h4 class="panel-title">
        <a data-toggle="collapse" data-parent="#accordion" href="#collapseOne">
          Collapsible Group Item #1
        </a>
      </h4>
    </div>
    <div id="collapseOne" class="panel-collapse collapse">
      <div class="panel-body">
        Anim pariatur cliche reprehenderit, enim eiusmod high life accusamus terry richardson ad squid.
      </div>
    </div>
  </div>
  <div class="panel panel-default">
    <div class="panel-heading">
      <h4 class="panel-title">
        <a data-toggle="collapse" data-parent="#accordion" href="#collapseTwo">
          Collapsible Group Item #2
        </a>
      </h4>
    </div>
    <div id="collapseTwo" class="panel-collapse collapse">
      <div class="panel-body">
        Anim pariatur cliche reprehenderit, enim eiusmod high life accusamus terry richardson ad squid.
      </div>
    </div>
  </div>
  <div class="panel panel-default">
    <div class="panel-heading">
      <h4 class="panel-title">
        <a data-toggle="collapse" data-parent="#accordion" href="#collapseThree">
          Collapsible Group Item #3
        </a>
      </h4>
    </div>
    <div id="collapseThree" class="panel-collapse collapse">
      <div class="panel-body">
        Anim pariatur cliche reprehenderit, enim eiusmod high life accusamus terry richardson ad squid.
      </div>
    </div>
  </div>
</div>

我的 JS:

$(function() 

  var $active = true;

  $('.panel-title > a').click(function(e) 
    e.preventDefault();
  );

  $('.collapse-init').on('click', function() 
    if(!$active) 
      $active = true;
      $('.panel-title > a').attr('data-toggle', 'collapse');
      $('.panel-collapse').collapse('toggle': true, 'parent': '#accordion');
      $(this).html('Click to disable accordion behavior');
     else 
      $active = false;
      $('.panel-collapse').collapse('toggle': true, 'parent': '#accordion');
      $('.panel-title > a').removeAttr('data-toggle');
      $(this).html('Click to enable accordion behavior');
    
  );

);

【问题讨论】:

【参考方案1】:

更新答案

尝试打开设置为手风琴的折叠控件的多个面板,即使用data-parent 属性集,可能会出现很多问题和错误(请参阅multiple panels open after programmatically opening a panel 上的这个问题)

相反,最好的方法是:

    允许每个面板单独切换 然后,在适当的情况下手动强制执行手风琴行为。

要允许每个面板单独切换,在data-toggle="collapse" 元素上,将data-target 属性设置为.collapse 面板ID 选择器(而不是将data-parent 属性设置为父控件。您可以在问题Modify Twitter Bootstrap collapse plugin to keep accordions open 中了解更多信息。

大致来说,每个面板应该如下所示:

<div class="panel panel-default">
   <div class="panel-heading">
         <h4 class="panel-title"
             data-toggle="collapse" 
             data-target="#collapseOne">
             Collapsible Group Item #1
         </h4>
    </div>
    <div id="collapseOne" 
         class="panel-collapse collapse">
        <div class="panel-body"></div>
    </div>
</div>

要手动强制手风琴行为,您可以为在显示任何面板之前发生的折叠显示事件创建一个处理程序。使用它来确保在显示所选面板之前关闭任何其他打开的面板(请参阅answer to multiple panels open)。您还只希望在面板处于活动状态时执行代码。为此,请添加以下代码:

$('#accordion').on('show.bs.collapse', function () 
    if (active) $('#accordion .in').collapse('hide');
);

然后使用showhide 切换每个面板的可见性,并使用data-toggle 启用和禁用控件。

$('#collapse-init').click(function () 
    if (active) 
        active = false;
        $('.panel-collapse').collapse('show');
        $('.panel-title').attr('data-toggle', '');
        $(this).text('Enable accordion behavior');
     else 
        active = true;
        $('.panel-collapse').collapse('hide');
        $('.panel-title').attr('data-toggle', 'collapse');
        $(this).text('Disable accordion behavior');
    
);

Working demo in jsFiddle

【讨论】:

太接近了!如果我单击面板 1,然后单击 button 两次,然后单击面板 1,然后单击面板 2,然后再次单击 button,面板 2 将隐藏并保持关闭状态:-( 也可以通过重新加载来打破这一点,然后单击面板 1,然后单击面板 2,然后单击面板 3,然后单击 button,面板 3 在应显示时隐藏。 非常接近,我只想再次感谢你——我希望我能接受这两个答案,因为它们都是不可或缺的! @gordian,我已经将解决​​方案更新为我认为是所有建议中最干净的解决方案。不过,这是一次不错的集体努力。 我清理得更彻底了!因为我们可能不需要 &lt;p&gt; 元素,如果它是 panel-title jsFiddle 中唯一的东西 :)【参考方案2】:

无论出于何种原因,$('.panel-collapse').collapse('toggle': true, 'parent': '#accordion'); 似乎只能在第一次使用,并且只能用于展开可折叠。 (我尝试从展开的可折叠开始,它不会折叠。)

它可能只是在您第一次使用这些参数初始化折叠时运行一次。

使用showhide 方法你会获得更多的运气。

这是一个例子:

$(function() 

  var $active = true;

  $('.panel-title > a').click(function(e) 
    e.preventDefault();
  );

  $('.collapse-init').on('click', function() 
    if(!$active) 
      $active = true;
      $('.panel-title > a').attr('data-toggle', 'collapse');
      $('.panel-collapse').collapse('hide');
      $(this).html('Click to disable accordion behavior');
     else 
      $active = false;
      $('.panel-collapse').collapse('show');
      $('.panel-title > a').attr('data-toggle','');
      $(this).html('Click to enable accordion behavior');
    
  );

);

http://bootply.com/98201

更新

Granted KyleMit 似乎比我有更好的处理方式。他的回答和理解给我留下了深刻的印象。

我不明白发生了什么或为什么show 似乎在某些地方切换。

但是在搞砸了一段时间之后..终于有了以下解决方案:

$(function() 
  var transition = false;
  var $active = true;

  $('.panel-title > a').click(function(e) 
    e.preventDefault();
  );

  $('#accordion').on('show.bs.collapse',function()
    if($active)
        $('#accordion .in').collapse('hide');
    
  );

  $('#accordion').on('hidden.bs.collapse',function()
    if(transition)
        transition = false;
        $('.panel-collapse').collapse('show');
    
  );

  $('.collapse-init').on('click', function() 
    $('.collapse-init').prop('disabled','true');
    if(!$active) 
      $active = true;
      $('.panel-title > a').attr('data-toggle', 'collapse');
      $('.panel-collapse').collapse('hide');
      $(this).html('Click to disable accordion behavior');
     else 
      $active = false;
      if($('.panel-collapse.in').length)
        transition = true;
        $('.panel-collapse.in').collapse('hide');       
      
      else
        $('.panel-collapse').collapse('show');
      
      $('.panel-title > a').attr('data-toggle','');
      $(this).html('Click to enable accordion behavior');
    
    setTimeout(function()
        $('.collapse-init').prop('disabled','');
    ,800);
  );
);

http://bootply.com/98239

【讨论】:

谢谢@Trevor。使用show 方法的问题在于,如果您单击两次button 然后打开面板 1,当您单击打开面板 2 时面板 1 保持打开状态,几乎就像它不记得它的分组一样。 +1 好答案。扩展需要使用show:当您调用collapse函数(或任何引导函数)时,如果您传递一个对象,则意味着您启动坍塌。 toggle option 只有toggles the collapsible element on invocation(来自this answer) 谢谢@KyleMit!我现在离我更近了。我添加了一个检查,但现在我发现的问题是,如果你重新加载小提琴,然后显示面板 1 并单击 button 然后面板 1 关闭(切换)而不是像其他显示一样。 bootply.com/98224 @gordian,请参阅我的答案,它应该根据需要执行所有操作。 由于某种原因e.stopPropagation() 对我不起作用,所以我只是使用return false; 代替【参考方案3】:

为了在想要同时使用像.collapse( 'hide' ) 这样的“隐藏”和“显示”功能时保持手风琴特性不变,您必须在调用之前使用toggle: false 在对象中设置的父属性初始化可折叠面板“隐藏”或“显示”

// initialize collapsible panels
$('#accordion .collapse').collapse(
  toggle: false,
  parent: '#accordion'
);

// show panel one (will collapse others in accordion)
$( '#collapseOne' ).collapse( 'show' );

// show panel two (will collapse others in accordion)
$( '#collapseTwo' ).collapse( 'show' );

// hide panel two (will not collapse/expand others in accordion)
$( '#collapseTwo' ).collapse( 'hide' );

【讨论】:

【参考方案4】:

经过测试的最佳解决方案是放置以下小 sn-p,它将折叠在您加载时已经打开的手风琴选项卡。在我的情况下,最后第六个选项卡是打开的,所以我让它在页面加载时折叠起来。

 $(document).ready()
      $('#collapseSix').collapse("hide");
 

【讨论】:

以上是关于Bootstrap 3折叠手风琴:折叠所有作品,但在保持数据父级的同时不能全部展开的主要内容,如果未能解决你的问题,请参考以下文章

Bootstrap 4:手风琴不会折叠卡片

在页面刷新/导航时保留 Twitter Bootstrap 折叠状态

将 Font Awesome 5 与 Bootstrap 3 折叠组件一起使用——在折叠时更改箭头图标?

Bootstrap 4嵌套折叠“数据父级”不起作用

Bootstrap 在悬停时折叠手风琴

html Bootstrap 4a手风琴(折叠)表