当前项目是在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>
实际代理在问价中很多,希望读者可以看懂,不做全部呈现了。但是根据代码走,逻辑还是比较清晰的,不懂请留言。