移動端導航欄有個很常見的摺疊選單,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這個值得過渡過程耗費了時間
-
獲取容器真實height
- 網上搜了一下,拜讀了內容loading載入後高度變化CSS3 transition體驗優化,看到了這個方法
//思路:取消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