【问题标题】:jQuery change html text by iterating over arrayjQuery通过遍历数组来改变html文本
【发布时间】:2016-08-10 00:25:09
【问题描述】:

如果我写html:

<script  src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>
<h1 id="message">
</h1>

和JS:

messages = ["Here", "are", "some", "messages."]

$(function() {

  for (var i = 0; i < messages.length; i++) {
    $('#message').html(messages[i]).delay(1000);
  }

});

并加载页面,我希望看到数组中的每个字符串显示之间都有延迟。但是,我看到的只是“消息”。出现。似乎 for 循环在执行任何延迟之前立即遍历数组中的每个值。

我已经看到了另一种获得所需视觉结果的方法 (How can I change text after time using jQuery?),但我想知道为什么早期的方法不起作用。执行此代码时发生了什么?

【问题讨论】:

  • delay() 是异步的,但循环不是,因此循环在延迟之前完成并显示数组中的最后一个元素。你需要使用回调函数
  • 出现'messages'的原因是因为它是循环完成对对象的迭代时的最后一项。您需要在循环外创建另一个变量来保存整个内容。

标签: javascript jquery arrays


【解决方案1】:

这就是我会延迟我的消息更改的方式。

function delayLoop(delay, messages) {
  var time = 100;

  $(messages).each(function(k, $this) {
      setTimeout(function()
      {
          $("#message").html($this); 
      }, time)
      time += delay;
  });
}
delayLoop(1000, ["Here", "are", "some", "messages."]);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="message">
</div>

我所做的只是将每条消息延迟一个额外的延迟时间。 它在异步模式下工作,因此不会阻塞用户界面,并且消息将一个接一个地显示。

编辑:

从 .html 中删除了 .delay,它是多余的。

【讨论】:

  • 没有必要同时使用setTimeoutdelay,因为两者已经是异步的。你可以简单地做类似$(messages).each(function(i, message) { setTimeout(function() { $('#message').html(message); }, delay * i); });
  • 谢谢我没有注意到我这样做了,我实际上只是复制并粘贴了他的消息功能,因为没有必要重写整个东西但现在已经修复了,谢谢。跨度>
  • 您还将this 传递给 html 调用,即使 this 在 setTimeout 回调中未定义。
  • 是的,我知道,已修复。真的没想到它会运行我不喜欢给别人一个答案我相信他们需要学习所以如果你指出他们正确的方向......无论如何上面是固定的你可以运行它。
【解决方案2】:

请注意,jQuery 的delay 专门用于效果;像html 这样的方法不使用效果队列,因此不受delay 的影响。

使用 JavaScript 的原生 setTimeout 函数可以更好地解决这个问题。有很多方法可以做到这一点;事实上,你甚至不需要 jQuery!

let messages = ["Here", "are", "some", "messages."];
let delay = 1000;
let header = document.getElementById("message");

messages.forEach(function(message, i) {
  setTimeout(function() {
    header.innerText = message;
  }, delay * i);
});
&lt;h1 id="message" /&gt;

【讨论】:

    【解决方案3】:

    你需要一些类似

    的东西
    $(function() {
      for (var i = 0; i < messages.length) {
        var done=false;
        $('#message').html(messages[i]).delay(1000).queue(function(){
         done=true;
         $(this).dequeue();
        });
         if(done==true){ 
          i++;
         }
       }
    });
    

    【讨论】:

    • 在查看 JQluv 的答案时,它比我的效率高得多。继续使用他的。
    【解决方案4】:

    感谢您的回答和 cmets——非常有帮助。

    我还发现这篇文章很有帮助:Node.js synchronous loop,并从中写了这个(也有效):

    function changeText() {
        var msg = messages.shift();
      $('#message').html(msg).show(0).delay(1000).hide(0, function() {
        if (messages.length > 0) {
            changeText();
        }
      });
    }
    

    (我使用 .show 和 .hide 是因为没有它们,只有一个数组值出现。我不知道为什么会这样,但这是另一个问题。)

    【讨论】:

      猜你喜欢
      • 2020-11-08
      • 1970-01-01
      • 1970-01-01
      • 2011-10-19
      • 2021-09-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多