2016-11-03 40 views
0

我使用的打字機效果從this answer on SO打算有第一個div類型輸出,其次是第二個div(當第一個div輸入完成時)。如何使.each()等到每次迭代完成

<div class="text"> 
Lorem ipsum dolor sit amet... 
</div> 
<div class="text"> 
Cras eros augue, tempor... 
</div> 

JS:

// Create typewrite function as jQuery plugin: 
// (From https://stackoverflow.com/a/22266737/3217306) 
$.fn.typeText = function() { 
    var keystrokeDelay = 10, 

     self = this, 
     str = self.html(), 
     i = 0, 
     isTag, 
     text; 

    self.html(""); 

    (function type() { 
     text = str.slice(0, ++i); 
     if (text == str) { 
      console.log("completed typing"); 
      return; 
     } 
     self.html(text); 

     var char = text.slice(-1); 
     if (char == "<") { 
      isTag = true; 
     } 
     if (char == ">") { 
      isTag = false; 
     } 

     if (isTag) { 
      return type(); 
     } 
     setTimeout(type, keystrokeDelay); 
    }()); 
}; 

var textElements = $(".text"); 

// For each div.text, type them out 
textElements.each(function() { 
    $(this).typeText(); 
}); 

麻煩的是,無論是在同一時間打出來。我嘗試了許多涉及承諾,回調等不同的事情,但我無法讓他們爲這種情況工作。

JSFiddle

+0

嘗試使用遞歸函數,而不是'each' –

回答

2

有很多方法可以做到這一點,我將展示的方式只是一個選項:

... 
self.html(""); 

$.fn.typeText.queue = $.fn.typeText.queue || [] // make a shared variable between the elements that call this function. This will call them in the order that were added 

$.fn.typeText.queue.push(function type() { 
    text = str.slice(0, ++i); 
    if (text == str) { 
     console.log("completed typing"); 
     $.fn.typeText.queue.shift(); // remove first element which just ended 
     if ($.fn.typeText.queue.length > 0) { // if there are more 
      $.fn.typeText.queue[0]() // start next 
     } 
     return; 
    } 
    ... 
    setTimeout(type, keystrokeDelay); 
}); 

if ($.fn.typeText.queue.length == 1) { // if its the first element added or no elements are in queue, call it 
    $.fn.typeText.queue[0](); 
} 

}; 

這將爲要素的任何數量的工作,並會打電話給他們,以便。如果你希望有一組同時運行但在每個組內運行的組,則它很容易改變功能來完成它。一種方法是到一個數組傳遞給方法,並用這個來代替$ .fn.typeText.queue

完整代碼:

$.fn.typeText = function() { 
 
    var keystrokeDelay = 10, 
 
    
 
    \t \t self = this, 
 
     str = self.html(), 
 
     i = 0, 
 
     isTag, 
 
     text; 
 

 
    self.html(""); 
 

 
    $.fn.typeText.queue = $.fn.typeText.queue || [] 
 

 
$.fn.typeText.queue.push(function type() { 
 
     text = str.slice(0, ++i); 
 
     if (text == str) { 
 
      console.log("completed typing"); 
 
\t \t \t \t \t \t $.fn.typeText.queue.shift(); // remove first element which just ended 
 
      if ($.fn.typeText.queue.length > 0) { // if there are more 
 
       $.fn.typeText.queue[0]() // start next 
 
      } 
 
      return; 
 
     } 
 
     self.html(text); 
 

 
     var char = text.slice(-1); 
 
     if (char == "<") { 
 
      isTag = true; 
 
     } 
 
     if (char == ">") { 
 
      isTag = false; 
 
     } 
 

 
     if (isTag) { 
 
      return type(); 
 
     } 
 
     setTimeout(type, keystrokeDelay); 
 
    }) 
 

 
    if ($.fn.typeText.queue.length == 1) { // if its the first element added or no elements are in queue, call it 
 
     $.fn.typeText.queue[0](); 
 
    } 
 
    
 
}; 
 

 
var textElements = $(".text"); 
 

 
textElements.each(function() { 
 
    $(this).typeText(); 
 
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> 
 
<div class="text"> 
 
    Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse condimentum erat non velit euismod, ac tristique orci hendrerit. Nullam varius in sem sed tempor. Maecenas tincidunt, nisi a accumsan maximus, lectus sem congue ligula, eget tempus neque lacus quis arcu. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Quisque at purus eleifend, euismod nibh ut, auctor nulla. Phasellus convallis nulla urna, porta egestas justo sollicitudin sit amet. 
 
</div> 
 
<div class="text"> 
 
    Cras eros augue, tempor ut velit ornare, dignissim sollicitudin mi. Duis accumsan diam sed nulla sodales mattis. Pellentesque nec efficitur nunc, vitae rutrum massa. Pellentesque metus metus, consequat in auctor non, lobortis eget ligula. Sed volutpat, dui vulputate congue iaculis, justo massa consequat turpis, id facilisis ex sapien eget ligula. Praesent eu erat lorem. Mauris id dui orci. Mauris vitae urna tortor. Proin luctus id purus non maximus. 
 
</div>

+0

這是否進去'$ .fn.typeText =函數(){}'? – binaryfunt

+1

@binaryfunt添加片段 – juvian

+0

我有點困惑'$ .fn.typeText.queue = $ .fn.typeText.queue || []'。什麼'|| []'做? – binaryfunt

0

使用setTimeout和計數器,你在jQuery插件中做了。

var textElements = $(".text"); 
var counter = 0; 

function typeDiv(){ 
    if(counter < textElements.length -1){ 
      textElements[counter].typeText(); 
      counter += 1; 
      setTimeout(typeDiv, 2000); 
     } 
}