前言
CSS Transitions(过渡)被应用于元素指定的属性变化时,该属性经过一段时间,逐渐地过渡到最终需要的值;而CSS Animations(动画)只是在应用时执行之前定义好的操作,它提供更细粒度的控制。[1]
局限
animation 的局限
CSS animation 需要提前设置好起点、终点的状态,不能很好地的去干涉动画的状态。 例如现在需要异步获取数据,渲染列表,列表高度和数据的个数相关,我们不能提前知道个数,因此下面这段动画存在问题:当行数不足20行,列表滑动完毕后,仍在滑动。
即:我们很难控制 animation 的状态,即使通过 js 的方式,也是繁琐的(参看参考文献[1]探查css 找到对应的 keyframes)
.slidedown-css {
animation: slidedown 2s infinite;
}
@keyframes slidedown {
from {
transform: translateY(0);
}
to {
transform: translateY(2rem * 20); // 每行2rem高度,共20行
}
}
不过,animation 提供了一个很好的属性,可以进行动画的中断。 例如,鼠标悬停时,终止上述动画:
.slidedown-css:hover {
animation-play-state: paused; // 兼容时,加上前缀
}
transition 的局限
CSS transition 用 js 控制状态的方式,很好实现。但是目前该方法无法实现动画的中断。 即,通过js方式获取到当前的状态,然后改变对应的属性值,也不能阻止本次动画的执行。所有可以看到,该动画结束后,才能停止到指定的属性值。如:
.slidedown-css {
transition: transform 2s infinite;
}
{
start(data) {
// data has loaded
this.dom = document.getElementsByClassName('slidedown-css')[0];
dom.style.transform = `translateY(${2 * data.length}rem)`;
},
// 响应鼠标悬浮事件
onMouseOver() {
const matrix = document.defaultView.getComputedStyle(this.dom); // matrix(1, 0, 0, 1, 31, 21)
const y = Number(matrix.substring(7).replace(')', '').split(','));
// 设置动画时间为 0
this.dom.style.transition = `transform 0s infinite`;
this.dom.style.transform = `translateY(${y})`;
}
}
上面代码意图是:鼠标悬停时,将滚动位置停留在当前鼠标的位置。
但是我们会看到,动画到达终点状态后,才迅速的跳到鼠标移入时的高度。因此出现页面闪动现象。
特性
虽然存在这样的局限,但是有几个时机,我们可以利用。
transition
transition 动画,提供了动画状态事件,可以很好地响应动画状态变化:
const transition = document.querySelector('.transition');
const message = document.querySelector('.message');
transition.addEventListener('transitionrun', function() {
message.textContent = 'transitionrun 触发了';
});
transition.addEventListener('transitionstart', function() {
message.textContent = 'transitionstart 触发了';
});
transition.addEventListener('transitionend', function() {
message.textContent = 'transitionend 触发了';
});
利用上面几个事件,我们可以进行一些操作,如动画结束后,触发另外一个动画的执行。
其中transitionrun
、transitionstart
不同的地方是:
- transitionrun 在 transition 创建的时候被触发。(或者说在某个 delay 开始的时候)
- transitionstart 在动画实际开始的时候被触发。 (或者说在某个 delay 结束的时候);[2]
参考文献: