平时在做业务中,我们会有一些 CSS 动画的需求,用的最频繁的应该是过渡 transition
或者 动画 animation
。
现在有一个伪需求是,在动画完成之后,删除其对应的 dom
。
我们能通过setTimeout 延迟指定的动画时间
后来执行回调函数,删除其对应的 dom
。
上面的做法有一个问题是,在动画执行期间,如果有大量占用浏览器资源的其他高优先级任务,造成页面卡顿,动画实际的执行时间变长,导致 js
提前删除了动画元素对应的 dom
。不优雅,而且有结束时间不准确的情况。
那么 css 有没有提供类似的API呢?
接下来介绍两个关键的 JS 事件
1、transitionend
transitionend
事件会在 CSS transition
结束后触发。
基本用法如下:
element.addEventListener('transitionend', handler)
复制代码
有两点需要注意:
1、如果监听元素有多个属性都有过渡动画, transitionEnd 会在多个属性完成后多次触发。
解决方法:通过 falg 控制回调函数执行次数。
2、如果监听元素的 children
也有过渡,也会在 children
的过渡完成后处触发。
解决方法:可以通过判断 e.target === element 判断是不是当前监听元素
2、animationend
element.addEventListener('animationend', handler)
复制代码
有一点需要注意:
如果监听元素的 children
也有动画,也会在 children
的动画完成后处触发。
解决方法:可以通过判断 e.target === element 判断是不是当前监听元素
兼容性
不同的浏览器需要返回不同的前缀。下面贴上transition相关代码 (animation大同小异):
function whichTransitionEvent() {
const el = document.createElement('container');
const transitions = {
transition: 'transitionend',
OTransition: 'oTransitionEnd',
MozTransition: 'transitionend',
WebkitTransition: 'webkitTransitionEnd',
};
for (let t in transitions) {
if (el.style[t] !== undefined) {
return transitions[t];
}
}
}
const event = whichTransitionEvent();
event && element.addEventListener(event, handler);
复制代码
浏览器兼容情况 可以看到主流浏览器均已支持。