自适应高度的过渡

概述

css里面,要想元素从一个状态过渡到另外一个状态,就需要有数值的变化,比如opacity、transform、background-color等等,但是我们可能经常遇到的一个问题就是,一个元素的高度是自适应的,也就是height:auto,然后我们想要过渡到0,这样我们设置transition后是没法实现的,因为auto到0不是两个具体值之间的过程,因此这里总结一起高度自适应过渡的处理方式。

效果

实现

关键requestAnimationFrame

window.requestAnimationFrame() 告诉浏览器------你希望执行一个动画,并且要求浏览器在下次重绘之前调用指定的回调函数更新动画。该方法需要传入一个回调函数作为参数,该回调函数会在浏览器下一次重绘之前执行。出了这个方法之外,setTimeout也是可以的,但是更加推荐requestAnimationFrame方法。

注意点

  • 首先我们我们通过动态获取需要过渡元素的高度,然后再动态设置过渡元素的高度,这样就有了两个具体数值之间的产生,因此transition就可以生效。
  • js动态设置高度的时候,高度那块不能同步更改,因为js执行是同步的,最终渲染的时候,是最后设置的那个值。
  • 动画执行完毕,需要移除我们动态设置的高度,因此这样产生的副作用可能影响后续动态追加的元素,这样就会产生无法自适应高度的bug.

代码

``

js 复制代码
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
    <style>
      .box {
        width: 300px;
        margin: auto;
        overflow: hidden;
        background-color: palegreen;
        transition: 0.3s;
      }
      .box-item {
        line-height: 40px;
        text-align: center;
      }
    </style>
  </head>
  <body>
    <button class="operate-button">折叠</button>
    <button class="add-button">追加</button>
    <div class="box">
      <div class="box-item">this is a text this is a text</div>
      <div class="box-item">this is a text this is a text</div>
      <div class="box-item">this is a text this is a text</div>
      <div class="box-item">this is a text this is a text</div>
      <div class="box-item">this is a text this is a text</div>
      <div class="box-item">this is a text this is a text</div>
      <div class="box-item">this is a text this is a text</div>
      <div class="box-item">this is a text this is a text</div>
      <div class="box-item">this is a text this is a text</div>
      <div class="box-item">this is a text this is a text</div>
      <div class="box-item">this is a text this is a text</div>
      <div class="box-item">this is a text this is a text</div>
      <div class="box-item">this is a text this is a text</div>
      <div class="box-item">this is a text this is a text</div>
      <div class="box-item">this is a text this is a text</div>
      <div class="box-item">this is a text this is a text</div>
    </div>

    <script>
      let operateButton = document.querySelector(".operate-button");
      let addButton = document.querySelector(".add-button");
      let box = document.querySelector(".box");
      let tag = false;
      //   监听过渡执行完毕
      box.addEventListener("transitionend", () => {
        console.log(tag);
        if (!tag) {
          box.style.removeProperty("height");
        }
      });
      operateButton.addEventListener("click", () => {
        if (tag) {
          box.style.height = "auto";
          const height = box.offsetHeight;
          box.style.height = 0;
          //下次重绘(下一帧)执行
          requestAnimationFrame(() => {
            box.style.height = height + "px";
          });
          operateButton.textContent = "折叠";
        } else {
          const height = box.offsetHeight;
          box.style.height = height + "px";
           //下次(下一帧)重绘执行
          requestAnimationFrame(() => {
            box.style.height = 0;
          });
          operateButton.textContent = "展开";
        }
        tag = !tag;
      });

      addButton.addEventListener("click", () => {
        const cloneLiItem = document.querySelector(".box-item").cloneNode(true);
        box.appendChild(cloneLiItem);
      });
    </script>
  </body>
</html>
相关推荐
一条上岸小咸鱼1 分钟前
Kotlin 基本数据类型(四):String
android·前端·kotlin
我是哈哈hh15 分钟前
【Node.js】ECMAScript标准 以及 npm安装
开发语言·前端·javascript·node.js
张元清38 分钟前
电商 Feeds 流缓存策略:Temu vs 拼多多的技术选择
前端·javascript·面试
一枚前端小能手39 分钟前
🎨 CSS布局从入门到放弃?Grid让你重新爱上布局
前端·css
晴空雨39 分钟前
React 合成事件原理:从事件委托到 React 17 的重大改进
前端·react.js
魏嗣宗42 分钟前
Node.js 网络编程全解析:从 Socket 到 HTTP,再到流式协议
前端·全栈
pepedd86443 分钟前
还在开发vue2老项目吗?本文带你梳理vue版本区别
前端·vue.js·trae
pepedd8641 小时前
浅谈js拷贝问题-解决拷贝数据难题
前端·javascript·trae
@大迁世界1 小时前
useCallback 的陷阱:当 React Hooks 反而拖了后腿
前端·javascript·react.js·前端框架·ecmascript
跟橙姐学代码1 小时前
学Python别死记硬背,这份“编程生活化笔记”让你少走三年弯路
前端·python