2016-02-26 46 views
0

这里是小提琴https://jsfiddle.net/8p2jjr18/animationend听众和setTimeout的

的想法是做一个渐强和香草JS推荐的淡出旋转。问题是,当函数在setTimeout的第四次运行时,在选择第一和后续元素没有得到.fade类。相反,.hidden类被马上(而不是等待被应用的.fade类的类来结束动画)应用,它搅乱了整个画面。

我试图把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; 
    }; 
} 

所以,球员,我有两个问题:

1)为什么我不能放置break指令到for循环的结束?

2)为什么函数在第四次及以后的setTimeout循环中不能正常工作?

谢谢!

回答

1

随着您当前的代码,随着时间的推移,您将继续添加动画结束事件侦听器,从而在每个推荐元素上产生多个事件侦听器。你需要做的只是附加一个事件监听器,它根据元素的当前状态采取适当的行动。

有两种方法可以处理这个问题。首先是为每个元素创建一个事件监听器。

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); 
    } 

这里给每个元素赋予它自己的事件监听器函数。当演出动画结束时,该功能被触发并且元素被赋予渐变类。当淡入淡出动画结束时,该函数再次被触发并且该元素被隐藏,并且下一个元素被赋予show类。 See updated fiddle

另一种方法是给父元素提供一个事件监听器。由于event bubbling,只要有子元素触发动画结束事件,就会触发此功能。

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

+0

非常感谢您提供了一个无可挑剔的答案和简洁明了的代码! – Dronich