【问题标题】:How to consequently change letter using javascript with a second delay using setTimeout? [duplicate]因此,如何使用 javascript 更改字母并使用 setTimeout 进行第二次延迟? [复制]
【发布时间】:2019-03-17 15:05:27
【问题描述】:

我正在尝试使用 setTimeout 在 DOM 中从 a->b->c->d->e 显示文本,每个字母之间有 1 秒的延迟。然而,结果是字母从 'a' an 立即变为 'e' 而没有显示 'b' 'c' 'd'。但是,所有字母都显示在控制台中,没有 1 秒的延迟。对不起,我的解释令人困惑。

function changeLetter() {
  const symbols = ['Ai', 'a', 'b', 'c', 'd']
  let symbol
  for (let i = 0; i < symbols.length; i++) {
    setTimeout(() => {
      symbol = symbols[i]
      console.log(symbol)
      document.getElementById("change").innerHTML = symbol;
    }, 1000)
  }
}
changeLetter()
&lt;h1 id="change"&gt;&lt;/h1&gt;

【问题讨论】:

    标签: javascript


    【解决方案1】:

    问题是整个 for 循环在第一次超时触发之前运行。

    处理这个问题的一种优雅方法是从超时本身调用函数。这样下一个超时不会开始,直到前一个完成(这使用% symbols.length 使其连续循环):

    const symbols = ['Ai', 'a', 'b', 'c', 'd']
    
    function changeLetter(i) {
        setTimeout(() => {
            symbol = symbols[i]
            document.getElementById("change").innerHTML = symbols[i];
            changeLetter((i+1) % symbols.length) 
        }, 1000)
    }
    
    
    changeLetter(0)
    &lt;h1 id="change"&gt;&lt;/h1&gt;

    或者,您可以只使用setInterval

    const symbols = ['Ai', 'a', 'b', 'c', 'd']
    count = 0
    let inthandle = setInterval(() => {
      document.getElementById("change").innerHTML = symbols[count];
      count = (count + 1) % symbols.length
    }, 1000)
    &lt;h1 id="change"&gt;&lt;/h1&gt;

    【讨论】:

      【解决方案2】:

      发生这种情况是因为所有 setTimeout() 调用都在 1000 毫秒注册并重叠,因此您会看到到 d 的转换是瞬间发生的,因此会跳过其间的元素。

      您需要为下一个元素连续注册setTimeout()。所以只需1000 * (i + 1) 将在setTimeout 调用中执行此操作。第一个元素为 1000 毫秒,下一个元素为 2000 毫秒,依此类推。

      function changeLetter() {
        const symbols = ['Ai', 'a', 'b', 'c', 'd']
        let symbol
        for (let i = 0; i < symbols.length; i++) {
          setTimeout(() => {
            symbol = symbols[i]
            console.log(symbol)
            document.getElementById("change").innerHTML = symbol;
          }, 1000 * (i + 1))
        }
      }
      changeLetter()
      &lt;h1 id="change"&gt;&lt;/h1&gt;

      【讨论】:

        【解决方案3】:

        问题是您的 for 循环会立即执行。因此,您同时实例化了 5 个 setTimeout 调用,它们都同时执行。由于最后一个 setTimeout 的回调将值更改为 d,您会立即看到。

        相反,您需要递归地延迟调用每个setTimeout,直到前一个调用完成。像这样的:

        const symbols = ['a','b','c'];
        const currentSymbol = 0;
        
        function changeLetter() {
          if (currentSymbol < symbols.length) {
            document.getElementById("change").innerHTML = symbols[currentSymbol];
            currentSymbol++;
            setTimeout(changeLetter, 1000);
          }
        }
        
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2019-06-10
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2021-09-19
          • 1970-01-01
          • 2022-08-02
          • 2021-02-23
          相关资源
          最近更新 更多