【react】对于高度未知的盒子,使用transition实现展开收起过渡动画
对于未知高度的盒子,如何实现展开收起的transition过渡效果
![盒子展开收起动画](https://img2022.cnblogs.com/blog/2372626/202202/2372626-20220213185524467-1243548309.gif)
我们经常碰到一种情况,点击某个按钮需要对某个盒子的内容进行展开收起,很多时候我们会用display:none | block;实现其内容的出现和消失。但这个办法做出来的视觉效果很生硬,这时候我们就想用transition做过渡动画的缓冲效果,达到优化视觉体验的目的。
不过,由于盒子高度是由内容撑起的,我们也不知道height最终会是多少,而transition对于height从0-auto,从0-100%经常是不起作用的。所以直接这么用,一般以失败告终。
下面是我针对这一场景的解决办法。中心思想就是:让父元素的height属性进行transition过渡,只有一个子元素用来存放展开内容,展开时将子元素的height赋值给父元素。
HTML代码:
<p>
开合动画开关按钮:
<i
className={`icon ${this.isShowContent ? "open" : ""}`}
onClick={this.showContent}
>
>
</i>
</p>
<div className="transition-wrapper">
<div className="content transition-content">
我是内容,我是内容,我是内容,我是内容,我是内容,
我是内容,我是内容,我是内容,我是内容,我是内容,
我是内容,我是内容,我是内容,我是内容,我是内容,
我是内容,我是内容,我是内容,我是内容,我是内容,
我是内容,我是内容,我是内容,我是内容,我是内容,
我是内容,我是内容,我是内容,我是内容,我是内容,
我是内容,我是内容,我是内容,我是内容,我是内容,
我是内容,我是内容,我是内容,我是内容,我是内容,
</div>
</div>
JS代码:
// 对于未知高度盒子的展开合并动画
showContent = () => {
this.setState({ isShowContent: !this.isShowContent });
this.isShowContent = !this.isShowContent;
const wrapper = document.querySelector(".transition-wrapper");
if (this.isShowContent) {
/*
因为子元素只是被父元素(height:0px;overflow:hidden)隐藏起来了,
所以它的高是真实的(由内容撑起),因此我们可以获得子元素的高,
并将它赋值给父元素,使父元素拥有内容展开后的高。
以此达到触发transition过渡动画的目的。
*/
const content = document.querySelector(".transition-content");
const height = content.offsetHeight;
wrapper.style.height = height + "px";
} else {
wrapper.style.height = 0;
}
};
CSS代码:
.icon {
padding: 5px 10px;
width: fit-content;
height: fit-content;
display: inline-block;
background-color: rgba(34, 2, 77, 0.5);
color: #fff;
text-align: center;
transform: rotate(0);
cursor: pointer;
}
.icon.open {
transform: rotate(90deg);
}
.transition-wrapper {
border: 1px solid #000;
width: fit-content;
height: 0px;
overflow: hidden;
transition: height 0.5s ease;
.content {
background-color: aqua;
border: 5px white solid;
width: 300px;
}
}