使用 setTimeout 的函数会在后续调用中抛出

Function using setTimeout throws on subsequent calls

我正在尝试一些简单的东西,一种打字效果:

var i = 0;
var txt = "eco eco"
var speed = 1;
function typeWriter(idtxt) {
  if (i < txt.length) {
    document.getElementById(idtxt).innerHTML += txt.charAt(i);
    i++;
    setTimeout(typeWriter, speed);
  }
};
<button class="remo-btn" onclick="typeWriter('demo')">
<p id="demo"></p>

当我对 id 进行硬编码时,代码按预期工作:

document.getElementById("demo").innerHTML += txt.charAt(i);

但是当我这样传递 id 时:

document.getElementById(idtxt).innerHTML += txt.charAt(i);

它只有 returns 第一个字母,在本例中为“e”(来自 echo)。

有人可以帮助我吗?

您在 setTimeout 中调用 typeWriter 时忘记传入 idtxt:

var i = 0;
var txt = "eco eco"
var speed = 1000;
function typeWriter(idtxt) {
  if (i < txt.length) {
    document.getElementById(idtxt).innerHTML += txt.charAt(i);
    i++;
    setTimeout(() => typeWriter(idtxt), speed);
  }
};
<button class="remo-btn" onclick="typeWriter('demo')">
<p id="demo"></p>

setTimeout(typeWriter, speed );更改为setTimeout(typeWriter, speed, idtxt );
您缺少发送 idtxt 参数

PS cahnge 也 var speed = 1000; 1s == 1000ms

var i = 0;
var txt = "eco eco"
var speed = 1000;
function typeWriter(idtxt) {
  if (i < txt.length) {
    document.getElementById(idtxt).innerHTML += txt.charAt(i);
    i++;
    setTimeout(typeWriter, speed, idtxt );
  }
};
<button class="remo-btn" onclick="typeWriter('demo')">
<p id="demo"></p>

发生这种情况是因为 idtxt 变量在第一次调用 typeWriter 后超出范围。您可以通过将参数作为 setTimeout 的第一个参数传递给对 typeWriter 的后续调用。像这样:

setTimeout(typeWriter, speed, idtxt);

您可以在此处阅读有关 setTimeout 的更多信息:https://developer.mozilla.org/en-US/docs/Web/API/WindowOrWorkerGlobalScope/setTimeout

您可以在此处详细了解为什么需要这样做:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Closures

var i = 0;
var txt = "eco eco"
var speed = 1000;
function typeWriter(idtxt) {
  if (i < txt.length) {
    document.getElementById(idtxt).innerHTML += txt.charAt(i);
    i++;
    setTimeout(typeWriter, speed, idtxt);
  }
};
<button class="remo-btn" onclick="typeWriter('demo')">
<p id="demo"></p>

此外,您的意思可能是 speed 等于 1000(1 秒)。 setTimeout 的延迟以毫秒为单位。

ES6 为此提供了其他方式。

例如 Promise 管理:

const delay = ms => new Promise(r => setTimeout(r, ms))
  ,    txt  = 'Hello, world!'
  ;
async function typeWriter(idtxt)
  {
  const elm = document.getElementById(idtxt)
  for await (let letter of txt)
    {
    elm.textContent += letter
    await delay(500)
    }
  }
<button class="remo-btn" onclick="typeWriter('demo')">remo-btn</button>

<p id="demo"></p>