你可能不知道的JS动画事件

平时在做业务中,我们会有一些 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);
复制代码

浏览器兼容情况 image.png 可以看到主流浏览器均已支持。

参考链接

transitionend
animationend

Guess you like

Origin juejin.im/post/7075161699216523294