最近工作中遇到个 transition 优化体验的问题,记录一下:
盒子的高度是内容撑起来的,盒子内容有两种形态:展开和收起,所以盒子高度也会跟着变化。本来打算简单用 transition 加一个过渡效果,但是遇到了问题。
如果盒子高度变化是确定的(比如:100px -> 300px),那使用 transition 没有什么问题,但是现在盒子高度是 auto,甚至初始高度和目标高度都是不知道的(auto),这样 transition 肯定就不会工作了,所以需要给盒子高度设置固定值。
我们可以使用 js 获取元素的当前高度,内容变化后盒子的高度就是目标高度,所以步骤:
1、获取初始盒子高度 height
2、内容改变
3、设置盒子 高度为 初始高度 height
4、给盒子加上 transition style
5、设置盒子高度为 targetHeight
代码如下:
const funTransitionHeight = (element: HTMLElement) => {
const height = getComputedStyle(element).height; // 初始高度
element.style.transition = "none"; // 清除过渡效果
element.style.height = "auto";
// TODO 这里需要补充代码:使内容变化
nextTick(() => {
// nextTick 理解为 等内容变化渲染完成后
const targetHeight = getComputedStyle(element).height; // 当前盒子高度是内容变化后的目标高度
element.style.height = height;
element.style.transition = "height .35s";
clearTimeout(timer);
timer = setTimeout(() => {
// 不知道为什么不加 setTimeout 不生效。。。
element.style.height = targetHeight;
});
});
};
由于项目使用的 vue,所以上面使用了 nextTick(不用也不生效)。
最后看看效果
使用 transition 前
使用 transition 后
:::info
本文参考张鑫旭大佬的 文章 :::