代码之家  ›  专栏  ›  技术社区  ›  Samuel Hulla

使用setInterval错误地更新了innerHTML

  •  2
  • Samuel Hulla  · 技术社区  · 6 年前

    我正在尝试用纯js创建一个基本的打字机。

    我基本上是想模仿某人用键盘以可信的方式打字。问题是,由于某种原因,我的节点的文本似乎不显示,我似乎无法理解为什么

    function get_random_in_interval(min, max){
       return Math.floor(Math.random() * (max - min + 1)) + min;
     }
    
    function typewriter(textinput){
      var min = 1;
      var max = 3;
      var rand = get_random_in_interval(min, max);
      var into = document.getElementById('textentry');
    
    
      for (i = 0; i < textinput.length; i++){
            var timer = setInterval(function(){
            if (i >= textinput.length){
              clearInterval(timer);
            }
    
            into.innerHTML += textinput.charAt(i);
          }, rand * 1000);
      }
    
    }
    
    
     var test = "Hello, I am a <b>text</b> \n \n I tried doing some freaky stuff";
     typewriter(test);
    #textentry {
      border: 10px solid #2c3e50;
      width: 400px;
      height: 100px;
      background-color: #95a5a6;
      font-family: Consolas, monospace;
      color: #FFF;
    }
    <div id="textentry"></div>

    我最好的猜测是 setInterval() 这里的功能不正确。问题是,我真的想不出我应该把它放在哪里。如果我把 设置间隔() 外部 for() 循环,然后它会工作(自己测试),但它会以随机间隔打印整个字符串,而不仅仅是所需的字符。

    3 回复  |  直到 6 年前
        1
  •  2
  •   Sheshank S.    6 年前

    这里有一个更简单的解决方案(与另一个相比):

    这基本上使用了 setInterval 然后停下来 i 变得比长度还长。

    function get_random_in_interval(min, max){
       return Math.floor(Math.random() * (max - min + 1)) + min;
     }
    
    function typewriter(textinput){
      var min = 1;
      var max = 3;
      var rand = get_random_in_interval(min, max);
      var into = document.getElementById('textentry');
      var i = 0;
      let Htmlstring = ""; // Credit to Certain Performance for the idea
    
      var timer = setInterval(function(){
        Htmlstring += textinput.charAt(i);
        into.innerHTML = Htmlstring;
        i++;
        if (i > textinput.length) {
          clearInterval(timer);
        }
      }, get_random_in_interval(min, max)*30);
      
    
    }
    
    
     var test = "Hello, I am a <b>text</b> \n \nI tried doing some freaky stuff";
     typewriter(test);
    #textentry {
      border: 10px solid #2c3e50;
      width: 400px;
      height: 100px;
      background-color: #95a5a6;
      font-family: Consolas, monospace;
      color: #FFF;
    }
    <pre id="textentry"></pre>
        2
  •  2
  •   Mark    6 年前

    这里有一些好的答案。我发布这个只是作为一个不同的选择,因为有很多方法可以做到这一点。你可以用 setTimeout 而不是 setInterval 一个小的递归函数。

    function get_random_in_interval(min, max){
        return Math.floor(Math.random() * (max - min + 1)) + min;
        }
    
    function typewriter(textinput){
        const min = 60;
        const max = 120;
        const into = document.getElementById('textentry');
        const type = (i) => {
            let rand = get_random_in_interval(min, max);
            setTimeout(() => {
                into.innerHTML = textinput.slice(0,i++)
                if (i < textinput.length) type(i)
            }, rand)
        }
        type(0)
    }
    
    var test = "Hello, I am a <b>text</b> \n \n I tried doing some freaky stuff";
    typewriter(test);
    #textentry {
      border: 10px solid #2c3e50;
      width: 400px;
      height: 100px;
      background-color: #95a5a6;
      font-family: Consolas, monospace;
      color: #FFF;
    }
    <div id="textentry"></div>
        3
  •  1
  •   CertainPerformance    6 年前

    所有的间隔都被设定了 同步地 是的。到那个时候 typewriter 功能结束(在任何间隔运行之前); i 等于 textinput.length ,所以 into.innerHTML += textinput.charAt(i); 不起作用。

    您还想在每次迭代之前暂停—要做到这一点,可能最容易做到 await Promise 在循环中。(你绝对不想 setInterval )

    const get_random_in_interval = (min, max) => (
      new Promise(res => setTimeout(res, Math.floor(Math.random() * (max - min + 1)) + min))
    );
    
    async function typewriter(textinput){
      var min = 5;
      var max = 45;
      var into = document.getElementById('textentry');
      let htmlStr = '';
      for (let i = 0; i < textinput.length; i++){
        await get_random_in_interval(min, max);
        htmlStr += textinput.charAt(i);
        into.innerHTML = htmlStr;
      }
    }
     var test = "Hello, I am a <b>text</b> <br> <br> I tried doing some freaky stuff";
     typewriter(test);
    #textentry {
      border: 10px solid #2c3e50;
      width: 400px;
      height: 100px;
      background-color: #95a5a6;
      font-family: Consolas, monospace;
      color: #FFF;
    }
    <div id="textentry"></div>

    更换 \n S与 <br> 如果你想输入html。