首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >如何让.each()等到每次迭代完成

如何让.each()等到每次迭代完成
EN

Stack Overflow用户
提问于 2016-11-03 09:37:07
回答 4查看 102关注 0票数 0

我使用来自this answer on SO的打字机效果,目的是让第一个div输入输出,然后是第二个div (当第一个div完成输入时)。

代码语言:javascript
复制
<div class="text">
 Lorem ipsum dolor sit amet...
</div>
<div class="text">
 Cras eros augue, tempor...
</div>

JS:

代码语言:javascript
复制
// 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

EN

回答 4

Stack Overflow用户

发布于 2016-11-03 09:58:04

有很多方法可以做到这一点,我将展示的方法只是一种选择:

代码语言:javascript
复制
... 
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

完整代码:

代码语言:javascript
复制
$.fn.typeText = function() {
    var keystrokeDelay = 10,
    
    		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");
						$.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();
});
代码语言:javascript
复制
<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>

票数 2
EN

Stack Overflow用户

发布于 2016-11-03 09:59:18

像在jQuery插件中一样使用setTimeout和计数器。

代码语言:javascript
复制
var textElements = $(".text");
var counter = 0;

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

Stack Overflow用户

发布于 2018-07-30 02:09:48

请注意,如果您将想要具有打字机效果的div放入一个div中,它们将一个接一个地自动进行。

代码语言:javascript
复制
<div class="text">
  <p>Lorem ipsum dolor sit amet…</p>
  <p>Cras eros augue, tempor…</p>
</div>
代码语言:javascript
复制
$(".text").typeText();
/* Instead of
textElements.each(function() {
    $(this).typeText();
}); */

参见this JSFiddle

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/40392475

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档