Bootstrap: 展开一个部分时折叠其他部分

我正在做一个 Rails 应用程序,并试图实现与 Twitter 的 Bootstrap 崩溃相关的特殊功能。请耐心听我解释。

我目前有以下看法:

enter image description here

当单击这些按钮时,它们的数据切换 div 将被展开。视图的设置如下:

    <button class="btn dropdown" data-toggle="collapse" data-target="#keys"><i class="icon-chevron-right"></i> Keys <span class="badge badge-info pull-right"><%= @app.keys.count %></span></button>
<button class="btn dropdown" data-toggle="collapse" data-target="#attrs"><i class="icon-chevron-right"></i> Attributes</button>
<button class="btn dropdown" data-toggle="collapse" data-target="#edit"><i class="icon-chevron-right"></i> Edit Details</button>


<div class="collapse indent" id="keys">
<!--content-->
</div>


<div class="collapse indent" id="attrs">
<!--content-->
</div>


<div class="collapse" id="edit">
<!--content-->
</div>

我把它们设置成这样,因为我希望按钮并排排列。如果我将按钮移动到它们展开/折叠的视图的正上方,那么这些按钮就会叠加在一起。

因此,我的最终目标是让这三个按钮并排放置,让它们折叠并展开各自的部分。然而,目前的设置有点尴尬。例如,如果有人展开键部分,然后展开属性部分,他们必须滚动到键部分的下面。

这个问题有两种可能的解决办法。一种是按一个按钮会导致另外两个按钮崩溃。这将意味着在任何给定的时间,只有其中一个部分被扩展。

我认为更好的解决方案是,当键被展开时,右边的按钮移动到键 div 的底部,当属性被展开时,编辑细节按钮移动到该 div 的底部。这可能吗?我已经尝试过让按钮堆叠在一起,然后通过 css 改变它们的相对位置,但是这并不奏效,因为当其中一个部分被展开时,其他的按钮会在展开部分的中间出现尴尬的位置。

最后,我想尝试做到这一点,没有手风琴风格的行为提到了 Twitter 的引导页面,但如果有人可以说服我从设计的立场,这是更好的,我当然会重新考虑。

194522 次浏览

Using data-parent, first solution is to stick to the example selector architecture

<div id="myGroup">
<button class="btn dropdown" data-toggle="collapse" data-target="#keys" data-parent="#myGroup"><i class="icon-chevron-right"></i> Keys  <span class="badge badge-info pull-right">X</span></button>
<button class="btn dropdown" data-toggle="collapse" data-target="#attrs" data-parent="#myGroup"><i class="icon-chevron-right"></i> Attributes</button>
<button class="btn dropdown" data-toggle="collapse" data-target="#edit" data-parent="#myGroup"><i class="icon-chevron-right"></i> Edit Details</button>


<div class="accordion-group">
<div class="collapse indent" id="keys">
keys
</div>


<div class="collapse indent" id="attrs">
attrs
</div>


<div class="collapse" id="edit">
edit
</div>
</div>
</div>

Demo (jsfiddle)

Second solution is to bind on the events and hide the other collapsible elements yourself.

var $myGroup = $('#myGroup');
$myGroup.on('show.bs.collapse','.collapse', function() {
$myGroup.find('.collapse.in').collapse('hide');
});

Demo (jsfiddle)

PS: the strange effect in the demos is caused by the min-height set for the example, just ignore that.


Edit: changed the JS event from show to show.bs.collapse as specified in Bootstrap documentation.

If you stick to HTML structure and proper selectors according to the Bootstrap convention, you should be alright.

<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="#collapse1">Collapsible Group 1</a>
</h4>
</div>
<div id="collapse1" class="panel-collapse collapse in">
<div class="panel-body">Lorem ipsum dolor sit amet, consectetur adipisicing elit,
sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam,
quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.</div>
</div>
</div>
<div class="panel panel-default">
<div class="panel-heading">
<h4 class="panel-title">
<a data-toggle="collapse" data-parent="#accordion" href="#collapse2">Collapsible Group 2</a>
</h4>
</div>
<div id="collapse2" class="panel-collapse collapse">
<div class="panel-body">Lorem ipsum dolor sit amet, consectetur adipisicing elit,
sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam,
quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.</div>
</div>
</div>
<div class="panel panel-default">
<div class="panel-heading">
<h4 class="panel-title">
<a data-toggle="collapse" data-parent="#accordion" href="#collapse3">Collapsible Group 3</a>
</h4>
</div>
<div id="collapse3" class="panel-collapse collapse">
<div class="panel-body">Lorem ipsum dolor sit amet, consectetur adipisicing elit,
sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam,
quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.</div>
</div>
</div>
</div>

DEMO

The Method Works Properly For me:

var lanopt = $(".language-option");


lanopt.on("show.bs.collapse",".collapse", function(){
lanopt.find(".collapse.in").collapse("hide");
});

If you don't want to change your markup, this function does the trick:

jQuery('button').click( function(e) {
jQuery('.collapse').collapse('hide');
});

Whenever a BUTTON is clicked, all sections become collapsed. Then bootstrap opens the one you selected.

Bootstrap 3 example with side by side buttons below the content

.panel-heading {
display: inline-block;
}


.panel-group .panel+.panel {
margin: 0;
border: 0;
}


.panel {
border: 0 !important;
-webkit-box-shadow: none !important;
box-shadow: none !important;
background-color: transparent !important;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>


<!-- Latest compiled and minified CSS -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">


<!-- Latest compiled and minified JavaScript -->
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js" integrity="sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa" crossorigin="anonymous"></script>




<div class="panel-group" id="accordion">
<div class="panel panel-default">
<div id="collapse1" class="panel-collapse collapse in">
<div class="panel-body">Lorem ipsum dolor sit amet, consectetur adipisicing elit,
sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam,
quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.</div>
</div>
</div>
<div class="panel panel-default">
<div id="collapse2" class="panel-collapse collapse">
<div class="panel-body">Lorem ipsum dolor sit amet, consectetur adipisicing elit,
sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam,
quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.</div>
</div>
</div>
<div class="panel panel-default">
<div id="collapse3" class="panel-collapse collapse">
<div class="panel-body">Lorem ipsum dolor sit amet, consectetur adipisicing elit,
sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam,
quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.</div>
</div>
</div>
</div>
<div class="panel-heading">
<h4 class="panel-title">
<a data-toggle="collapse" data-parent="#accordion" href="#collapse1">Collapsible Group 1</a>
</h4>
</div>
<div class="panel-heading">
<h4 class="panel-title">
<a data-toggle="collapse" data-parent="#accordion" href="#collapse2">Collapsible Group 2</a>
</h4>
</div>
<div class="panel-heading">
<h4 class="panel-title">
<a data-toggle="collapse" data-parent="#accordion" href="#collapse3">Collaple Group 3</a>
</h4>
</div>

Bootstrap 3 example with side by side buttons above the content

.panel-heading {
display: inline-block;
}


.panel-group .panel+.panel {
margin: 0;
border: 0;
}


.panel {
border: 0 !important;
-webkit-box-shadow: none !important;
box-shadow: none !important;
background-color: transparent !important;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>


<!-- Latest compiled and minified CSS -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">


<!-- Latest compiled and minified JavaScript -->
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js" integrity="sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa" crossorigin="anonymous"></script>


<div class="panel-heading">
<h4 class="panel-title">
<a data-toggle="collapse" data-parent="#accordion" href="#collapse1">Collapsible Group 1</a>
</h4>
</div>
<div class="panel-heading">
<h4 class="panel-title">
<a data-toggle="collapse" data-parent="#accordion" href="#collapse2">Collapsible Group 2</a>
</h4>
</div>
<div class="panel-heading">
<h4 class="panel-title">
<a data-toggle="collapse" data-parent="#accordion" href="#collapse3">Collaple Group 3</a>
</h4>
</div>
<div class="panel-group" id="accordion">
<div class="panel panel-default">
<div id="collapse1" class="panel-collapse collapse in">
<div class="panel-body">Lorem ipsum dolor sit amet, consectetur adipisicing elit,
sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam,
quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.</div>
</div>
</div>
<div class="panel panel-default">
<div id="collapse2" class="panel-collapse collapse">
<div class="panel-body">Lorem ipsum dolor sit amet, consectetur adipisicing elit,
sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam,
quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.</div>
</div>
</div>
<div class="panel panel-default">
<div id="collapse3" class="panel-collapse collapse">
<div class="panel-body">Lorem ipsum dolor sit amet, consectetur adipisicing elit,
sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam,
quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.</div>
</div>
</div>
</div>

If you are using Bootstrap 4, and you don't want to change your markup:

var $myGroup = $('#myGroup');
$myGroup.on('show.bs.collapse','.collapse', function() {
$myGroup.find('.collapse.show').collapse('hide');
});

Use this:

$('.panel-defaul.ph').on('show.bs.collapse', function () {
$(this).children('.panel-heading').addClass('panel-heading-collapsed');
$('.panel-defaul.ph').not(this).children('.panel-collapse').removeClass('in');
});

In bootstrap 4 to close all collapseds works like this:

ACTION:

<button id="CloseAll" class="btn btn-primary" type="button" data-toggle="collapse">Close All</button>

JQUERY:

$(document).ready(function() {
$("#CloseAll").on('click', function() {
$(".collapse").removeClass("show");
});
});

working like a charm here for bootstrap 4>4.1.1

var myGroup = $('your-list');


myGroup.on('show.bs.collapse','.collapse', function() {
myGroup.find('.collapse.show').collapse('hide');
});

This was helpful for me:

    jQuery('button').click( function(e) {
jQuery('.in').collapse('hide');
});

It's collapsed already open section. Thnks to GrafiCode Studio

For Bootstrap v5

Add the data-bs-parent attribute to the collapse elements. Thanks to @Diana for the update.

For Bootstrap v4.1

Add the data-parent attribute to the collapse elements instead on the button.

<div id="myGroup">
<button class="btn dropdown" data-toggle="collapse" data-target="#keys"><i class="icon-chevron-right"></i> Keys  <span class="badge badge-info pull-right">X</span></button>
<button class="btn dropdown" data-toggle="collapse" data-target="#attrs"><i class="icon-chevron-right"></i> Attributes</button>
<button class="btn dropdown" data-toggle="collapse" data-target="#edit"><i class="icon-chevron-right"></i> Edit Details</button>


<div class="accordion-group">
<div class="collapse indent" id="keys"  data-parent="#myGroup">
keys
</div>


<div class="collapse indent" id="attrs"  data-parent="#myGroup">
attrs
</div>


<div class="collapse" id="edit"  data-parent="#myGroup">
edit
</div>
</div>
</div>

On Bootstrap5

Like noticed in the docu you can use the "data-bs-parent=.." attribute

If parent is provided, then all collapsible elements under the specified parent will be closed when this collapsible item is shown. (similar to traditional accordion behavior - this is dependent on the card class). The attribute has to be set on the target collapsible area.

see more in bootstrap5 docu