【react】对于高度未知的盒子,使用transition实现展开收起过渡动画

对于未知高度的盒子,如何实现展开收起的transition过渡效果

盒子展开收起动画

我们经常碰到一种情况,点击某个按钮需要对某个盒子的内容进行展开收起,很多时候我们会用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}
  >
    &gt;
  </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;
  }
}
posted @ 2022-02-13 18:36  leah-xx  阅读(1295)  评论(0编辑  收藏  举报