js輕鬆實現摺疊皮膚

方防坊放發表於2017-11-04

移動端導航欄有個很常見的摺疊選單,bootstrap有collapse外掛實現,jQuery UI有Accordion元件。最近用js無外掛實現一個這樣的效果。


探究歷程

  • display:none;

    • 直接採用display,雖然實現了控制容器的顯示和隱藏,但是效果生硬。

//jq或者zepeto的hide和show方法就是採用這個屬性
$(`#el`).hide();
$(`#el`).show();
/**
show: function() {
      return this.each(function() {
        //清除元素的內聯display="none"的樣式
        this.style.display == "none" && (this.style.display = null)
        //當樣式表裡的該元素的display樣式為none時,設定它的display為預設值
        if (getComputedStyle(this, ``).getPropertyValue("display") == "none") this.style.display = defaultDisplay(this.nodeName) //defaultDisplay是獲取元素預設display的方法
      })
    },
hide: function() {
      return this.css("display", "none")
    }
**/
  • transition: height 600ms;

    • 改變容器的高度,配合overflow: hidden;實現平滑動畫
//思路示例
//css
<style>
.box {
  height: 0px;
  transition: height 600ms;
  overflow: hidden;
  background: #4b504c;
}
</style>
//html
<button>...</button>
<div id="box" class="box">...</div>
//js
<script>
function openAndClose(){
        var el = document.getElementById("box");
        if(window.getComputedStyle(el).height == "0px"){
            el.style.height = "300px";
        }else{
            el.style.height="0px";
        }
}
</script>
//這樣雖然實現了效果,但是需要提前知道容器的高度
//如果設定height為auto,然而transition並沒有效果
  • transition: max-height 600ms;

    • 將transition的屬性換成max-height,max-height會限制元素的height小於這個值,所以我們將關閉狀態的值設成0,開啟狀態設定成足夠大
//思路示例
//css
<style>
.box {
  height: 300px;
  max-height: 0px;
  transition: max-height 600ms;
  overflow: hidden;
  background: #4b504c;
}
</style>
//html
<button>...</button>
<div id="box" class="box">...</div>
//js
<script>
function openAndClose(){
        var el = document.getElementById("box");
        if(window.getComputedStyle(el).maxHeight == "0px"){
            el.style.maxHeight = "1040px";
        }else{
            el.style.maxHeight="0px";
        }
}
</script>
//這樣過程中就會有個不盡人意的地方,關閉的時候總會有點延遲
//原因可能是maxHeight到height這個值得過渡過程耗費了時間
//思路:取消transition==》設定height:auto==》
//獲取容器真實height==》設定height:0==》
//設定transition==》觸發瀏覽器重排==》
//設定容器真實height
function openAndClose(){
        var el = document.getElementById("box");
        if(window.getComputedStyle(el).height == "0px"){
            // mac Safari下,貌似auto也會觸發transition, 故要none下~
            el.style.transition = "none";
            el.style.height = "auto";
            var targetHeight = window.getComputedStyle(el).height;
            el.style.transition = "height 600ms"
            el.style.height = "0px";
            el.offsetWidth;//觸發瀏覽器重排
            el.style.height = targetHeight;
        }else{
            el.style.height="0px";
        }
    }

其他

  • getComputedStyle() 方法獲取的是最終應用在元素上的所有CSS屬性物件|MDN

相關文章