2016-02-26 52 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