“animationend”有时不起火

时间:2015-04-24 19:31:05

标签: javascript html css css-animations

我有一个CSS动画,可以应用于带有CSS类的HTML元素。我还有一个事件监听器附加到animationend(它是一个现代Windows应用程序,所以浏览器只是IE11)。我所看到的是有时事件被触发,有时却没有。无论事件发生如何,我总能看到它在视觉上动画。对我来说,这看起来像某种竞争条件。

我在网上试图了解可能导致此事件未被解雇的原因,但我没有找到任何令人满意的结果。我在MDN上找到了以下内容:

  

注意:如果转换中止,则不会触发transitionend事件,因为动画属性的值在转换完成之前已更改。

UPDATE1: transitionendanimationend无关,因此此信息无关。

我不确定它是否适用于CSS动画。有没有人对这会导致什么有任何想法?如果有任何事件可以检测到动画中止,这也可能是一个有用的解决方法。

UPDATE2:我正在使用的当前解决方法:

element.addEventListener("animationstart", function () {
    setTimeout(function () {
        // do stuff
    }, animationDuration);
});

4 个答案:

答案 0 :(得分:0)

您的动画是否有可能没有结束?

查看animationcancel事件的文档:
https://developer.mozilla.org/en-US/docs/Web/Events/animationcancel

但是,浏览器支持似乎参差不齐(在Chrome 67中,"onanimationcancel" in HTMLElement.prototype为我返回了false)。

暂时似乎有必要使用setTimeout骇客。

答案 1 :(得分:0)

您可以使用此功能

SELECT t1.ID FROM Table t1
LEFT JOIN Table t2
  ON t1.Tag="XX" AND t1.Number = 13 AND t2.Tag="XX" AND t2.Number = 17

function onAnimationEnd(element, handler) { //- Create local variables var events = 'animationend transitionend webkitAnimationEnd oanimationend MSAnimationEnd webkitTransitionEnd otransitionend oTransitionEnd msTransitionEnd'; //- Bind event to element $(element).on(events, handler) //- Return received element return element } animation都结束时,此函数将绑定一个事件。

还要确保动画运行时没有删除或移动动画元素。

答案 2 :(得分:0)

使用IE11,您不必一定假定JS事件绑定将在CSS动画开始或结束之前发生。这种问题是断断续续的,频率/发作将取决于某些因素。

如果CSS动画的持续时间很短,并且动画在样式表准备就绪后立即开始,则可能无法及时应用JS事件绑定

我发现一个可靠的解决方法是使用JS通过className调用CSS动画。即,仅当通过JS应用className时,才应用CSS animation-name属性。

答案 3 :(得分:0)

FWIW,这仍然是一个问题。在某些情况下(到目前为止,我只在移动设备上进行过复制),带有清晰动画的某些元素并不总是会触发animationend事件。

编辑:原来问题出在动画after的内容上。 Safari不能可靠地处理它。我最终做了一个独特的删除线div并将其设置为动画。

function animateCSS(element, animationName, callback) {
    const node = typeof element == 'string' ? document.querySelector(element) : element;
    node.classList.add('animated', animationName);
    node.onanimationend = handleAnimationEnd;
    console.log('animateCSS', node, animationName);

    function handleAnimationEnd() {
        console.log('handleAnimationEnd', node, 'remove:', animationName);
        node.classList.remove('animated', animationName);
        node.onanimationend = null;

        if (typeof callback === 'function') callback(node);
    }
}

.strike {
    color: #e402b3;
    position: relative;
}
.strike:after {
    content: ' ';
    position: absolute;
    top: 50%;
    left: 2%;
    height: 2px;
    background: #e402b3;
    animation: strike 0.7s linear 0s 1 forwards;
    -webkit-animation: strike 0.7s linear 0s 1 forwards;
}
@keyframes strike {
    0% {
        width: 0%;
        color: #000;
    }
    100% {
        width: 96%;
        color: #e402b3;
    }
}
@-webkit-keyframes strike {
    0% {
        width: 0%;
        color: #000;
    }
    100% {
        width: 96%;
        color: #e402b3;
    }
}