[英]CSS3 animations - animationstart event won't fire when using transition:
Given the following:鉴于以下情况:
.slide{
transition: all 1s ease 0s;
transform: translateX(-100%);
}
and和
document.documentElement.addEventListener('animationstart', function() {
alert(1);
}, false);
the event won't fire.该事件不会触发。
However, if the CSS is :但是,如果 CSS 是:
.slide {
animation: slide 1s infinite
}
@keyframes slide {
from {
transform: translateX(0);
}
to {
transform: translateX(-100px);
}
}
It does fire.它确实火了。
How come?怎么来的? It's an animation in both cases, however, in the first case we don't use the keyframes which have other negative consequences.
在这两种情况下都是动画,但是,在第一种情况下,我们不使用具有其他负面影响的关键帧。
Isn't this an error in how browsers have implemented this feature?这不是浏览器如何实现此功能的错误吗?
Here is an example for the first:这是第一个示例:
http://jsbin.com/hizoyopimu/1/edit?html,css,js,console,output http://jsbin.com/hizoyopimu/1/edit?html,css,js,console,output
And second:第二:
http://jsbin.com/yegidehusi/1/edit?html,css,js,console,output http://jsbin.com/yegidehusi/1/edit?html,css,js,console,output
Is there something equivalent?有什么等价的吗?
TL;DR (Short Answer): TL; DR(简答):
As of now there is no event that gets fired during the start of a transition.到目前为止,还没有在转换开始期间触发的事件。 Transitions always happen only when a triggering condition is satisfied and so the event which triggers the transition can roughly be considered as equivalent to the
transitionstart
event.转换总是只有在满足触发条件时才会发生,因此触发转换的事件可以粗略地视为等效于
transitionstart
事件。
In the below snippet, I have added a user-defined function ( transitionStart
) which gets called right after the .addClass('slide')
and this is kind of equivalent to transitionstart
.在下面的代码片段中,我添加了一个用户定义的函数 (
transitionStart
),它在.addClass('slide')
之后.addClass('slide')
调用,这有点等同于transitionstart
。
/* For Animation Start */ setTimeout(function() { $('.animated').removeClass('hide').addClass('slide'); }, 1000); $('.animated').bind('animationstart webkitAnimationStart', function() { console.log('Animation Started'); }); /* For Transition Start */ setTimeout(function() { $('.animated').removeClass('hide').addClass('slide'); transitionStart(); }, 1000); function transitionStart(){ console.log('Transition Started'); }
.element { padding: 10px; background-color: #ccc; width: 100px; height: 100px; } .element.animated.hide { display: none; } .animated.slide { animation: slide 1s infinite } @keyframes slide { from { transform: translateX(0); } to { transform: translateX(-100px); } } .element.transitioned.hide { transform: translateX(-100%); } .transitioned.slide { transition: all 2s ease-in 0s; transform: translateX(200%); }
<script src="https://cdnjs.cloudflare.com/ajax/libs/prefixfree/1.0.7/prefixfree.min.js"></script> <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <h3>Element with Animation</h3> <div class='element hide animated'> box </div> <h3>Element with Transition</h3> <div class='element hide transitioned'> box </div>
A transitionend
event is available and can be used to identify the ending point of the transition and then perform any required function calls or other process. transitionend
事件可用,可用于识别转换的结束点,然后执行任何所需的函数调用或其他过程。 The below snippet has a sample for this.下面的代码片段有一个示例。
setTimeout(function() { $('.transitioned').removeClass('hide').addClass('slide'); transitionStart(); }, 1000); function transitionStart(){ console.log('Transition Started'); } $('.transitioned').bind('transitionend', function() { console.log('Transition Ended'); });
.element { padding: 10px; background-color: #ccc; width: 100px; height: 100px; } .element.transitioned.hide { transform: translateX(-100%); } .transitioned.slide { transition: all 2s ease-in 0s; transform: translateX(200%); }
<script src="https://cdnjs.cloudflare.com/ajax/libs/prefixfree/1.0.7/prefixfree.min.js"></script> <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <h3>Element with Transition</h3> <div class='element hide transitioned'> box </div>
Long Answer:长答案:
First of all, animation
and transition
are not same even though they produce a gradual change of the values assigned to the properties.首先,
animation
和transition
并不相同,即使它们产生分配给属性的值的逐渐变化。 Below are some key differences:以下是一些主要区别:
hover
, click
etc) or when some extra class is added to the element through JS.hover
、 click
等)更改状态或通过 JS 向元素添加一些额外类时,才会启动转换。 Animations can start automatically when the page is loaded. You can read more about the differences between them and when one should be used in this article .你可以阅读更多关于应该在使用它们以及何时之间的差异这篇文章。
Animation events ( animationstart
, animationend
etc) will not fire for your first case (the one where you are using transition
) because there is no animation
or valid @keyframe
rule specified on the element.动画事件(
animationstart
、 animationend
等)不会在您的第一种情况(您正在使用transition
情况下)触发,因为元素上没有指定animation
或有效的@keyframe
规则。
As per W3C Spec
根据 W3C 规范
Any animation for which both a valid keyframe rule and a non-zero duration are defined will run and generate events;
定义了有效关键帧规则和非零持续时间的任何动画都将运行并生成事件; this includes animations with empty keyframe rules.
这包括具有空关键帧规则的动画。
As per current spec there is no specific event that is fired when a transition
is started unlike when an animation
starts.根据当前规范,与
animation
开始时不同,在开始transition
时没有触发特定事件。 In other words, there is no transitionstart
event.换句话说,没有
transitionstart
事件。 Currently there is only one transition event ( transitionend
) that is implemented.目前只有一个转换事件(
transitionend
)被实现。 ( W3C Spec ). ( W3C 规范)。
I cannot say for sure if it was a conscious decision to not implement transitionstart
event or it was just a miss.我不能肯定地说,不实施
transitionstart
事件是有意识的决定,还是只是一次失误。 But the fact is that we don't have an equivalent one at present.但事实是,我们目前没有一个等效的。
Personally, I do not see this as a big miss because the developer should know the exact trigger points for a transition
(like the addition of a new class via JS or through user interaction events which can also be detected via JS).就个人而言,我不认为这是一个很大的思念,因为开发人员应该知道确切的触发点的
transition
(如通过JS或通过它也可以通过JS检测到用户交互事件增加了一个新的类的)。 So, we can always say that a transition has started at the very same instant when the trigger condition was satisfied.因此,我们总是可以说在满足触发条件的同一时刻开始了转换。 For your case, the
transition
has started at the same time at which the .addClass('slide')
is executed.对于您的情况,
transition
已在执行.addClass('slide')
同时开始。 So, whatever extra steps you want to do (or) functions that you want to call can be called directly after the .addClass('slide')
is executed.因此,在执行
.addClass('slide')
之后,可以直接调用您想要执行(或)要调用的任何额外步骤。
Points to note:注意事项:
animationstart
event.animationstart
事件。 The reason is because the animationstart
event is fired only after the animation-delay
that is set has expired.animationstart
事件只有在设置的animation-delay
过期后才会触发。 In your snippet there is no delay for either the animation or transition and hence this is not a big issue.transition-delay
property and execute another time-out before calling the required functions (or) actions.transition-delay
属性的值并在调用所需的函数(或)操作之前执行另一个超时。transitionstart
event but it is non-standard and hence is not recommended.transitionstart
事件,但它是非标准的,因此不推荐。Now in 2020:现在是 2020 年:
When using transitions, you have to use transition
events instead of animation
events.使用过渡时,必须使用
transition
事件而不是animation
事件。
Compatability table (works even in Edge v42) 兼容性表(甚至适用于 Edge v42)
yourElement.addEventListener("transitionstart", () => {
alert("transitionstart");
});
Example:例子:
const div1 = document.querySelector(".div1"); div1.addEventListener("click", () => { div1.classList.toggle("transition"); }); div1.addEventListener("transitionstart", () => { console.log("transitionstart"); });
.div1{ transition: transform 1s ease-in-out; background-color: darkseagreen; display:inline-block; } .div1.transition{ transform: translateX(100px); } .div1.transition:after{ content: " again, when transition stopps!"; background-color: yellow; }
<div class="div1"> CLICK ME</div>
The following code works.以下代码有效。 Although you have specified animationstart for a listener , you have also defined the animation in css to be infinite which will cause the alert to fire only on the first initial start of the infinite loop .
尽管您已为侦听器指定了 animationstart,但您还在 css 中将动画定义为无限,这将导致警报仅在无限循环的第一次初始启动时触发。 If you want to detect the animation on every stop/start/repeat cycle: one option would be looping the animation with javascript instead of infinite css.
如果您想在每个停止/开始/重复循环中检测动画:一种选择是使用 javascript 而不是无限 css 循环动画。 Hopefully this helps your research.
希望这有助于您的研究。
.slide {
animation: slide 1s infinite
}
@keyframes slide {
from {
transform: translateX(0);
}
to {
transform: translateX(100px);
}
}
JS JS
var x = document.querySelector('.slide');
x.addEventListener('animationstart',function(){
alert(1)
},false)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.