animationend 监听器和 setTimeout
animationend listeners and setTimeout
这里是fiddlehttps://jsfiddle.net/8p2jjr18/
我们的想法是在原版 JS 中实现用户评价的淡入淡出旋转。问题是当函数在setTimeout中第四次运行时,selection中的第一个和后续元素没有得到.fade
class。相反,.hidden
class 立即应用(而不是等待 .fade
class 应用和 class 上的动画结束)和它搞乱了整个画面。
我试图将 break;
放入 for
循环的末尾而不是 if
语句的末尾(参见下面的示例),但这完全破坏了一切(只是只发生一次迭代),我不知道为什么。
function rotateTestimonials() {
for (var i = 0; i < testimonials.length; i++) {
if (testimonials[i].className === "testimonial show") {
testimonials[i].className = "testimonial fade";
testimonials[i].addEventListener("animationend", function () {
testimonials[i].className = "testimonial hidden";
if (i + 1 !== testimonials.length) {
testimonials[i+1].className = "testimonial show";
}
else {
testimonials[0].className = "testimonial show";
}
}, false);
};
break;
};
}
我有两个问题:
为什么我不能将 break
指令放入 for
循环的末尾?
为什么函数在 setTimeout
循环的第四次和以后的迭代中没有按预期工作?
使用您当前的代码,随着时间的推移,您将继续添加 animationend 事件侦听器,从而在每个证明元素上产生多个事件侦听器。您需要做的只是附加一个事件侦听器,它根据元素的当前状态采取适当的操作。
有两种方法可以处理这个问题。首先是为每个元素创建一个事件侦听器。
function createEventListener(i, testimonials){
return function(){
if (testimonials[i].className === "testimonial show"){
testimonials[i].className = "testimonial fade";
} else {
testimonials[i].className = "testimonial hidden";
testimonials[(i+1)%testimonials.length].className = "testimonial show";
}
}
}
var testimonials = document.getElementsByClassName("testimonials")[0].getElementsByClassName("testimonial");
for (var i = 0; i < testimonials.length; i++) {
testimonials[i].addEventListener("animationend", createEventListener(i, testimonials), false);
}
这里每个元素都有自己的事件侦听器函数。当显示动画结束时,该函数被触发,元素被赋予淡入淡出 class。当淡入淡出动画结束时,该函数再次被触发,元素被隐藏,下一个元素显示为 class。 See updated fiddle
另一种方法是为父元素提供单个事件侦听器。由于 event bubbling.
,只要子元素触发 animationend 事件,就会触发此函数
var testimonials = document.getElementsByClassName("testimonials")[0].getElementsByClassName("testimonial");
var i = 0;
document.getElementsByClassName('testimonials')[0].addEventListener('animationend', function(){
if (testimonials[i].className === "testimonial show"){
testimonials[i].className = "testimonial fade";
} else {
testimonials[i].className = "testimonial hidden";
i = (i+1)%testimonials.length;
testimonials[i].className = "testimonial show";
}
});
这里我们只有一个事件处理程序,它将在每个子动画事件上调用。它的功能与上面相同,检查当前元素的状态并相应地改变。 See updated fiddle
这里是fiddlehttps://jsfiddle.net/8p2jjr18/
我们的想法是在原版 JS 中实现用户评价的淡入淡出旋转。问题是当函数在setTimeout中第四次运行时,selection中的第一个和后续元素没有得到.fade
class。相反,.hidden
class 立即应用(而不是等待 .fade
class 应用和 class 上的动画结束)和它搞乱了整个画面。
我试图将 break;
放入 for
循环的末尾而不是 if
语句的末尾(参见下面的示例),但这完全破坏了一切(只是只发生一次迭代),我不知道为什么。
function rotateTestimonials() {
for (var i = 0; i < testimonials.length; i++) {
if (testimonials[i].className === "testimonial show") {
testimonials[i].className = "testimonial fade";
testimonials[i].addEventListener("animationend", function () {
testimonials[i].className = "testimonial hidden";
if (i + 1 !== testimonials.length) {
testimonials[i+1].className = "testimonial show";
}
else {
testimonials[0].className = "testimonial show";
}
}, false);
};
break;
};
}
我有两个问题:
为什么我不能将
break
指令放入for
循环的末尾?为什么函数在
setTimeout
循环的第四次和以后的迭代中没有按预期工作?
使用您当前的代码,随着时间的推移,您将继续添加 animationend 事件侦听器,从而在每个证明元素上产生多个事件侦听器。您需要做的只是附加一个事件侦听器,它根据元素的当前状态采取适当的操作。
有两种方法可以处理这个问题。首先是为每个元素创建一个事件侦听器。
function createEventListener(i, testimonials){
return function(){
if (testimonials[i].className === "testimonial show"){
testimonials[i].className = "testimonial fade";
} else {
testimonials[i].className = "testimonial hidden";
testimonials[(i+1)%testimonials.length].className = "testimonial show";
}
}
}
var testimonials = document.getElementsByClassName("testimonials")[0].getElementsByClassName("testimonial");
for (var i = 0; i < testimonials.length; i++) {
testimonials[i].addEventListener("animationend", createEventListener(i, testimonials), false);
}
这里每个元素都有自己的事件侦听器函数。当显示动画结束时,该函数被触发,元素被赋予淡入淡出 class。当淡入淡出动画结束时,该函数再次被触发,元素被隐藏,下一个元素显示为 class。 See updated fiddle
另一种方法是为父元素提供单个事件侦听器。由于 event bubbling.
,只要子元素触发 animationend 事件,就会触发此函数 var testimonials = document.getElementsByClassName("testimonials")[0].getElementsByClassName("testimonial");
var i = 0;
document.getElementsByClassName('testimonials')[0].addEventListener('animationend', function(){
if (testimonials[i].className === "testimonial show"){
testimonials[i].className = "testimonial fade";
} else {
testimonials[i].className = "testimonial hidden";
i = (i+1)%testimonials.length;
testimonials[i].className = "testimonial show";
}
});
这里我们只有一个事件处理程序,它将在每个子动画事件上调用。它的功能与上面相同,检查当前元素的状态并相应地改变。 See updated fiddle