以前实习的时候因为赶时间直接用bootstrap的插件collapse.js做了个折叠菜单, 对于一个原生控来说还是更倾向于自己写一个, 毕竟为了个折叠菜单引入jq和bootstrap有点太臃肿了。 于是又到了考验山寨能力的时候了-_-# 。
原版collapse.js的效果其实也不难,主要是在开合的过程中添加了css3的过渡效果。以下是原版与山寨版demo,同时点击预览,可明显感受到加载速度的区别。
DEMO:
Bootstrap原版Collapse
接下来是本人山寨版(山寨版结构简单,代码轻巧,无依赖^_^):
Collapse by native JS
打包下载出门左转Github ? Collapse By Native JS
以下是代码逻辑:
HTML的结构
<div class="collapseDiv">
<h3>Title1</h3>
<div class="collapse_body">
<div class="collapse_content">
content1<br />content1<br />content1<br />content1<br />content1<br />content1<br />content1<br />content1<br />content1<br />
</div>
</div>
</div>
<div class="collapseDiv">
<h3>Title2</h3>
<div class="collapse_body">
<div class="collapse_content">
content2<br />content2<br />content2<br />content2<br />content2<br />content2<br />content2<br />content2<br />content2<br />
</div>
</div>
</div>
<div class="collapseDiv">
<h3>Title3</h3>
<div class="collapse_body">
<div class="collapse_content">
content3<br />content3<br />content3<br />content3<br />content3<br />content3<br />content3<br />content3<br />content3<br />
</div>
</div>
</div>
<div class="collapseDiv">
<h3>Title4</h3>
<div class="collapse_body">
<div class="collapse_content">
content4<br />content4<br />content4<br />content4<br />content4<br />content4<br />content4<br />content4<br />content4<br />
</div>
</div>
</div>
CSS(要山寨就尽量山寨得彻底,外观样式全部从bootstrap的样式搬运过来):
* {
box-sizing:border-box;
-webkit-box-sizing:border-box;
}
body {
font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
font-size: 14px;
line-height: 1.42857143;
color: #333;
background-color: #fff;
margin: 2px;
}
a{
text-decoration: underline;
color: #666666;
}
a:hover{
text-decoration: none;
}
.collapseDiv{
color: #333;
border-radius: 4px;
background-color: #f5f5f5;
border:1px solid transparent;
border-color: #ddd;
box-shadow: 0 1px 1px rgba(0,0,0,.05);
margin-top: 5px;
margin-bottom: 0;
}
.collapseDiv h3{
font-size: 14px;
font-weight: bold;
color: #333;
border-color: #ddd;
padding-top: 5px;
padding-right: 15px;
padding-bottom: 5px;
padding-left: 15px;
background-color: #f5f5f5;
margin: 0;
}
.collapse_body {
background-color:#fff ;
position: relative;
height: 0;
overflow: hidden;
-webkit-transition-timing-function: ease;
-o-transition-timing-function: ease;
transition-timing-function: ease;
-webkit-transition-duration: .35s;
-o-transition-duration: .35s;
transition-duration: .35s;
-webkit-transition-property: height, visibility;
-o-transition-property: height, visibility;
transition-property: height, visibility
}
.collapse_content{
border-top: 1px solid #ddd;
background-color:#fff ;
padding:15px;
}
JS
//接受三个参数,分别是折叠菜单的外包div名称,是否关闭之前的折叠,默认开启的折叠内容
function Collapse(className,close_prev,default_open){
this._elements = [];
this._className = String(className);
this._previous = Boolean(close_prev)
this._default = typeof(default_open)==="number" ? default_open: -1
this.getCurrent
this.init();
}
//收集所有折叠菜单的div
Collapse.prototype.collectElementbyClass = function(){
this._elements = [];
var allelements = document.getElementsByTagName("div");
for(var i=0;i<allelements.length;i++){
var collapse_div = allelements[i];
if (typeof collapse_div.className === "string" && collapse_div.className === this._className){
var h3s = collapse_div.getElementsByTagName("h3");
var collapse_body = collapse_div.getElementsByClassName("collapse_body");
if(h3s.length === 1 && collapse_body.length === 1){
h3s[0].style.cursor = "pointer";
if(this._default === this._elements.length){
collapse_body[0].style.visibility = "visible";
collapse_body[0].style.height = collapse_body[0].scrollHeight+"px"
}else{
collapse_body[0].style.height = "0px";
collapse_body[0].style.visibility = "hidden";
}
this._elements[this._elements.length] = collapse_div;
}
}
}
}
Collapse.prototype.open = function(elm){
elm.style.visibility = "visible";
elm.style.height = elm.scrollHeight + "px"
}
Collapse.prototype.close = function(elm){
elm.style.height = "0px";
elm.style.visibility = "hidden";
}
Collapse.prototype.isOpen = function(elm){
return elm.style.visibility === "visible"
}
Collapse.prototype.getCurrent = function(header){
var cur ;
if(window.addEventListener){
cur = header.parentNode
}else{
cur = header.parentElement
}
return cur.getElementsByClassName("collapse_body")[0]
}
Collapse.prototype.toggleDisplay = function(header){
var cur = this.getCurrent(header)
//console.log(cur)
if(this.isOpen(cur)){
this.close(cur);
}else{
this.open(cur);
}
if(this._previous){
for(var i=0;i<this._elements.length;i++){
if(this._elements[i] !== (cur.parentNode||cur.parentElement)){
var collapse_body = this._elements[i].getElementsByClassName("collapse_body");
collapse_body[0].style.height = "0px";
collapse_body[0].style.visibility = "hidden";
}
}
}
}
Collapse.prototype.init = function(){
var instance = this;
this.collectElementbyClass();
if(this._elements.length === 0){
return;
}
for(var i=0;i<this._elements.length;i++){
var h3s = this._elements[i].getElementsByTagName("h3");
if(window.addEventListener){
h3s[0].addEventListener("click",function(){ instance.toggleDisplay(this);},false);
}else{
h3s[0].onclick = function(){instance.toggleDisplay(this);}
}
}
}
//传参
var myCollapse = new Collapse("collapseDiv",true);