用前端动画提升用户体验 JS动画和css transition 动画选择哪一个?

195 阅读4分钟

用前端动画提升用户体验 JS动画和css transition 动画选择哪一个?

在网页设计和开发中,动画是一种常用的技术,用于增强用户体验和界面的互动性。主要的动画类型包括CSS动画(animation),DOM动画和基于JavaScript的动画。此外,理解屏幕刷新率对于确保动画流畅性也非常重要。下面我将详细介绍这些概念。

DOM 动画

DOM 动画通常是指使用JavaScript 直接操作DOM元素的属性来创建动画效果。这种方法比CSS更灵活,可以实现更复杂的动画效果,但同时也更消耗性能。

 <!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>JS 动画</title>
  <style>
    /* 定义一个红色的盒子,初始位置在左上角 */
    .box {
      width: 100px;           /* 盒子的宽度为100像素 */
      height: 100px;          /* 盒子的高度为100像素 */
      position: relative;     /* 使用相对定位,便于通过left/top移动 */
      left: 0;                /* 初始时距离左侧为0 */
      top: 0;                 /* 初始时距离顶部为0 */
      background-color: red;  /* 盒子的背景色为红色 */
    }
  </style>
</head>

<body>

  <!-- 动画移动的盒子 -->
  <div class="box"></div>
  <script>
  
    // 获取页面中class为box的元素,赋值给box变量
    const box = document.querySelector('.box');

    // 设置盒子的初始left值为100px(即距离父元素左侧100像素)
    let left = 100;

    // 定义一个动画移动函数move
    function move() {
    
      left += 2;   //  每次调用left增加2像素,实现平滑移动
      box.style.left = left + 'px'; // 设置盒子的left样式属性,实现视觉上的移动

      //   判断当前left值是否小于300像素
      //   如果小于300,则继续调用move函数,实现动画效果
      //   requestAnimationFrame会在浏览器下一帧时自动调用move,动画更流畅
      if (left < 300) {
        requestAnimationFrame(move);
      }
      //   当left达到或超过300像素时,动画停止,不再调用move
    }

    // 启动动画,首次调用move函数
    move();
  </script>
</body>
</html>

image.png

在这个例子中,我们使用JavaScript,每次调用left增加2像素,实现平滑移动。 JS动画通过调用requestAnimationFrame,requestAnimationFrame会在浏览器下一帧时自动调用move,动画更流畅

requestAnimationFrame: 是浏览器提供的JavaScript API,用于请求在下一次屏幕重绘前执行动画回调函数, 确保动画与屏幕刷新率同步,提升流畅度并优化性能。

CSS 动画 - transition 过渡

  • CSS transition 属性是一个非常有用的工具,它允许你在网页元素的属性值发生变化时创建平时的动画效果。

  • transition 属性的主要作用在元素的属性值发生变化时,创建一个平滑的过渡效果。这可以避免属性值的突然变化,使变化看起来更加自然和舒适。

             <!DOCTYPE html> 
      <html lang="en"> 
      <head>
          <meta charset="UTF-8">
          <meta name="viewport" content="width=device-width, initial-scale=1.0"> 
          <title>JS 动画2</title>
          <style>
              .box{
                  width: 100px; /* 盒子宽度100px */
                  height: 100px; /* 盒子高度100px */
                  position: relative; /* 相对定位,用于配合left属性移动 */
                  left: 0; /* 初始左偏移0(相对于父元素) */
                  top:0; /* 初始上偏移0 */
                  background-color: red; /* 背景色为红色 */
                  transition: left 2s ease-out; /* 关键:定义left属性的过渡动画,持续2秒,缓动函数为ease-out(结束时变慢) */
              }
              .box.active{
                  left: 300px; /* 当添加active类时,左偏移变为300px,触发transition动画 */
              }
          </style>
      </head>
      <body>
          <div class="box"></div> <!-- 动画目标元素,初始无active类 -->
          <script>
              // 监听DOM内容加载完成事件(此时HTML解析完成,但可能未完全渲染)
              document.addEventListener('DOMContentLoaded',function(){ 
                  // setTimeout  延迟执行回调(即使延迟0ms,也会作为宏任务放入事件队列)
                  // 目的:等待浏览器完成页面渲染(渲染优先级高于宏任务)
                  setTimeout(()=>{
                      // 查询.box元素并添加active类,触发CSS transition动画
                      document.querySelector('.box').classList.add('active');
                  },0)   
              }
          </script>
      </body>
      </html>
    

image.png

在这个例子中:

  • transition: left 2s ease-out; 关键:定义left属性的过渡动画,持续2秒,缓动函数为ease-out(结束时变慢)
  • .box.active{
  • left: 300px; 当添加active类时,左偏移变为300px,触发transition动画 }

js 动画和css transition 动画选择哪一个?

JS动画 : 通过JavaScript(例如requestAnimationFrame) 修改元素样式实现动画,涉及到页面的重新绘制,需手动控制每一帧的状态,复杂度高,频繁的操作DOM js 性能开销的主要问题

CSS transition 动画 : 通过CSS属性(transition)声明元素状态变化时的过渡效果(如active触发)。比js省去了DOM对象的操作,仅需定义起始/结束状态,浏览器自动计算中间帧,代码简洁,不会像js一样触发那么多次重新绘制

总结

JS动画的“性能差”本质是 主线程阻塞 和 跨引擎通信 的开销,而CSS Transition因浏览器内置优化更适合大多数简单场景。但JS动画在复杂交互中仍不可替代,实际开发中需根据需求权衡。