原生JS模拟Bootstrap中的折叠(Collapse)插件

以前实习的时候因为赶时间直接用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);
 
    
    
阅读 7.1k更新于 2016-01-14
推荐阅读

蚂蚁金服海外银行诚招前端:JD:[链接] 简历请投:jiongjiong.lc@antfin.com

51 人关注
29 篇文章
专栏主页
目录