Javascript - 一次写出一个字母?

时间:2015-03-29 22:03:21

标签: javascript

这是我到目前为止所做的:

<div id='test'>

</div>

<script src='http://code.jquery.com/jquery-latest.js'></script>
<script>
    var timePerLetter = 2000;
    var newLineCharacter = '|';

    function printOut(text) {
        for(var i = 0; i < text.length; i++) {
            var CHAR = text[i];

            switch(CHAR) {
                case newLineCharacter:
                    setTimeout( $('#test').append('<br>'), timePerLetter);
                default:
                    setTimeout( $('#test').append(CHAR), timePerLetter);
            }
        }
    }

    printOut("HELLO ASDA| SD");
</script>

它打印出来应该有点。 它打印:

HELLO ASDA
| SD

但是,每个字母等待两秒钟,我该如何解决这个问题?

6 个答案:

答案 0 :(得分:5)

同步排队一堆异步操作。所以它们几乎同时执行。你应该做的是排队第一个,然后让它排队下一个。

var timePerLetter = 2000;
var newLineCharacter = '|';

function printOut(text) {
  var index = 0;

  var printNextLetter = function() {
    if (index < text.length) {
      var CHAR = text[index];

      switch(CHAR) {
        case newLineCharacter:
          $('#test').append('<br>');
          break;
        default:
          $('#test').append(CHAR);
          break;
      }

      index++;

      setTimeout(printNextLetter, timePerLetter);
    }
  }

  printNextLetter();
}

printOut("HELLO ASDA| SD");

答案 1 :(得分:1)

使用setTimeout函数递归调用printOut函数,而不是快速启动多个for的{​​{1}}循环。等待setTimeout执行再次致电setTimeout会在每个printOut之间提供完整的延迟。

要跟踪序列在过程中的位置,会将一个索引参数添加到setTimeout函数,默认为“0”

JSFiddle

printOut

答案 2 :(得分:1)

您应该在上一个中添加下一个setTimeout。如果您在开始时设置所有超时,并且延迟相同,则它们将同时或多或少地运行。

此外,您可以更新文本节点而不是html,以避免html注入。要保留换行符,请使用CSS white-space属性。

&#13;
&#13;
var timePerLetter = 500,
    newLineCharacter = '|',
    text = document.createTextNode('');
document.getElementById('test').appendChild(text);
function printOut(str) {
  var i = 0;
  (function main() {
    var char = str[i++];
    text.nodeValue += char == newLineCharacter ? '\n' : char;
    if(i < str.length)
      setTimeout(main, timePerLetter);
  })();
}
printOut("HELLO ASDA| SD");
&#13;
#test {
  white-space: pre-line;
}
&#13;
<div id='test'></div>
&#13;
&#13;
&#13;

答案 3 :(得分:1)

这可能就是你要找的东西:

var timePerLetter = 200;
var newLineCharacter = '|';

function printOut(text) {
    for(var i = 0; i < text.length; i++) {
        var CHAR = text[i];
        setTimeout(appendLetter, timePerLetter*i, CHAR);
    }
}

function appendLetter(character)
{
    if(newLineCharacter == character)
    {
        $('#test').append('<br>');
    }
    else
    {
        $('#test').append(character);
    }    
}

printOut("HELLO ASDA| SD");

使用JSFiddle here!

答案 4 :(得分:0)

在你的控制台中尝试这个 - 延迟的递归调用:

var startStr = 'Hello World';
var shiftAndPrint = function (segments) {
    var segment = segments.shift();
    console.log(segment);
    if (segments.length){
        setTimeout(shiftAndPrint.bind(null,segments),1000);
    }
}
shiftAndPrint(startStr.split(''));

答案 5 :(得分:0)

与使用bind的答案相同,但不使用bind()函数。

&#13;
&#13;
    var timePerLetter = 2000;
    var newLineCharacter = '|';

    function printOut(text) {
      for (var i = 0; i < text.length; i++) {
        setTimeout(
          function(j) {
            return function() {
              switch (text[j]) {
                case newLineCharacter:
                  setTimeout($('#test').append('<br>'), timePerLetter);
                  break;
                default:
                  setTimeout($('#test').append(text[j]), timePerLetter);
              }
            }
          }(i),
          timePerLetter * i
        );
      }
    }
    printOut("HELLO ASDA| SD");
&#13;
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id='test'>

</div>
&#13;
&#13;
&#13;