當前項目是在react項目中的,所以本案例代碼改變數據申明和數據更改都是react的方式
效果圖如下:
首先聲明幾個變量
constructor(props) { // 變量申明
super(props);
this.state = {
todayList: {}
}
this.view = null; //摺疊內容變量
this.animation1 = null; //動畫(收起)
this.animation2 = null; //動畫(展開)
this.heightList = {}; //摺疊內容高度(用於存儲)
this.stepDeHeight = this.stepDeHeight.bind(this); //動畫收起函數
this.stepGainHeight = this.stepGainHeight.bind(this); //動畫展開函數
}
然後,定義三個函數分別爲:動畫收起函數、動畫展開函數、面板的點擊事件
函數和api說明:
parseFloat():函數可解析一個字符串,並返回一個浮點數
https://www.runoob.com/jsref/jsref-parsefloat.html
requestAnimationFrame():執行關鍵幀動畫的方法
https://www.jianshu.com/p/f6d933670617
cancelAnimationFrame():消除關鍵幀動畫的方法
https://www.w3cschool.cn/fetch_api/fetch_api-5rzn2uyv.html
一下爲動畫效果的全部行數,你可以仔細按照流程走下去。代碼沒有一一做註釋。
//動畫收起函數
stepDeHeight(height) {
// cancelAnimationFrame(this.animation2)
if (parseFloat(this.view.style.height) > 0) {
this.view.style.height =
parseFloat(this.view.style.height) - height * 5 / 100 + "px";
this.animation1 = requestAnimationFrame(() => { this.stepDeHeight(height) });
} else {
this.view.style.height = 0;
cancelAnimationFrame(this.animation1)
// this.view.style.display='none'
return;
}
}
//動畫展開函數
stepGainHeight(height) {
// cancelAnimationFrame(this.animation1)
// this.view.style.display='block'
if (parseFloat(this.view.style.height) < height) {
this.view.style.height =
parseFloat(this.view.style.height) + height * 5 / 100 + "px";
this.animation2 = requestAnimationFrame(() => { this.stepGainHeight(height) });
} else {
this.view.style.height = height;
cancelAnimationFrame(this.animation2)
return;
}
}
//點擊事件
hiddenShow(index) {
this.view = document.getElementsByClassName('league-table')[index];
console.log(this.view.getBoundingClientRect().height)
if (this.view.getBoundingClientRect().height > 0) {
if (!this.heightList[index]) {
this.heightList[index] = this.view.getBoundingClientRect().height;
}
if (this.view.getBoundingClientRect().height == this.heightList[index]) {
this.view.style.height = this.view.getBoundingClientRect().height + 'px';
cancelAnimationFrame(this.animation2)
this.stepDeHeight(this.heightList[index])
}
} else {
cancelAnimationFrame(this.animation1)
console.log(this.heightList[index])
this.stepGainHeight(this.heightList[index])
}
}
最後,本案例是後臺返回一個數組,然後我通過map()遍歷出來,然後在return()裏面的面板內容中添加點擊事件。
// 面板顯示點擊view,如下所有內容都放到map遍歷div內
<div className="league-name"
onClick={() => { this.hiddenShow(index); }}>點我</div>
<div className="league-table" style={{ display: 'block' }}>
{..........存放面板內容..............}
</div>
實際代理在問價中很多,希望讀者可以看懂,不做全部呈現了。但是根據代碼走,邏輯還是比較清晰的,不懂請留言。