在视图之间设置动画(左右切换动画)

本文介绍了一种使用CSS transform属性在不同视图间进行平滑切换的动画方法,避免了使用left、top等属性可能引起的布局重绘问题,提高了动画性能。文章详细解释了如何创建一个包含列表视图和详情视图的容器,以及如何通过JavaScript控制类名切换来实现视图之间的动画过渡。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

您常常需要让用户在应用的各视图之间切换,不管是从列表换到详情视图,还是显示边栏导航。在这些视图之间设置动画可以吸引用户,并让您的项目更生动活泼。

1、使用transform来切换不同视图;避免使用 left、top 或任何其他会触发布局的属性。
2、确保使用的所有动画简洁明快,并且设置较短的持续时间。
3、考虑在屏幕尺寸增大时您的动画和布局如何变化。

力求使所有动画保持 60fps。这样,用户不会觉得动画卡顿,从而不会影响其使用体验。确保任何动画元素内容设置了 will-change。对于视图变换,您很可能要使用 will-change: transform。
在这里插入图片描述

为简单起见,我们假定有两个视图:一个列表视图和一个详情视图。当用户点按列表视图内的列表项时,详情视图将滑入屏幕,并且列表视图滑出。
在这里插入图片描述

要实现此效果,您需要一个容纳这两个视图的容器,并为容器设置 overflow: hidden。这样两个视图可以并排放在容器内,而不显示任何水平滚动条,并且每个视图可以按需在容器内侧向滑动。

<div class="container">
  <div class="view list-view">
    <ul class="list">
      <li class="list-item">
        列表
      </li>
    </ul>
  </div>
  <div class="view details-view">
    <button class="back-button">返回</button>
    <h1>详情页面</h1>
  </div>
</div>

此容器的 CSS 代码为:

container {
  width: 100%;
  height: 100%;
  overflow: hidden;
  position: relative;
}

容器的位置被设置为 relative。这意味着,其中的每个视图可以绝对定位在左上角,然后通过变形移动位置。此方法比使用 left 属性性能更佳(因为该属性会触发布局和绘图),并且通常更容易合理化。

.view {
  width: 100%;
  height: 100%;
  position: absolute;
  left: 0;
  top: 0;
  transition: transform 0.3s cubic-bezier(0.465, 0.183, 0.153, 0.946);
  will-change: transform;
}

屏幕之外的视图应变换到右侧,因此在这种情况下需要移动详情视图:

.details-view {
  transform: translateX(100%);
}

现在,需要少量 JavaScript 来处理类名。这将切换视图上相应的类名。

var container = document.querySelector('.container');
var backButton = document.querySelector('.back-button');
var listItems = document.querySelectorAll('.list-item');

function onViewChange(evt) {
  container.classList.toggle('view-change');
}

for (var i = 0; i < listItems.length; i++) {
  listItems[i].addEventListener('click', onViewChange, false);
}

backButton.addEventListener('click', onViewChange);

最后,我们为这些类名添加 CSS 声明。

.view-change .list-view {
  transform: translateX(-100%);
}

.view-change .details-view {
  transform: translateX(0);
}

完整代码如下:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
  <style>
    * {
      margin: 0;
      padding: 0;
    }
    html,body {
      width: 100%;
      height: 100%;
    }
    .container {
      width: 100%;
      height: 100%;
      overflow: hidden;
      position: relative;
    }
    .view {
      width: 100%;
      height: 100%;
      position: absolute;
      left: 0;
      top: 0;
      will-change: transform;
      transition: transform 0.3s cubic-bezier(0.465, 0.183, 0.153, 0.946);
    }
    .details-view {
      transform: translateX(100%);
    }
.view-change .list-view {
  transform: translateX(-100%);
}

.view-change .details-view {
  transform: translateX(0);
}
  </style>
</head>
<body>
<div class="container">
  <div class="view list-view">
    <ul class="list">
      <li class="list-item">
        列表
      </li>
    </ul>
  </div>
  <div class="view details-view">
    <button class="back-button">返回</button>
    <h1>详情页面</h1>
  </div>
</div>
  <script>
var container = document.querySelector('.container');
var backButton = document.querySelector('.back-button');
var listItems = document.querySelectorAll('.list-item');

function onViewChange(evt) {
  container.classList.toggle('view-change');
}

for (var i = 0; i < listItems.length; i++) {
  listItems[i].addEventListener('click', onViewChange, false);
}

backButton.addEventListener('click', onViewChange);
  </script>
</body>
</html>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

前端精髓

小礼物走一走,来CSDN关注我

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值