petrov
petrov

Reputation: 57

Java Script live typing

I am trying to write script which simulates live typing. I have made a loop to put each char every 0.15s, but it gives me all text at the same time. Should i use recursion, or maybe make something like "sleep" function?

var text = "Lorem ipsum dolor sit amet enim. Etiam ullamcorper. 
  Suspendisse a pellentesque dui, non felis. Maecenas malesuada elit 
  lectus felis, malesuada ultricies. Curabitur et ligula. Ut molestie a, 
  ultricies porta urna. Vestibulum commodo volutpat a, convallis ac, 
  laoreet enim. Phasellus fermentum in, dolor. Pellentesque facilisis. 
  Nulla imperdiet sit amet magna. Vestibulum dapibus, mau"

var allText = "";

function putText()
{
  document.getElementById("screen").innerHTML = allText;
};

function writeText()
{
    for(i=0; i<text.length; i++){
    allText = allText + text[i];
    setTimeout(putText, 150);
};
}

window.onclick  = writeText;

Upvotes: 0

Views: 243

Answers (2)

psgivens
psgivens

Reputation: 66

You can do this sort of recursively and just manually increment i instead of relying on a for loop:

function writeText() {
  if (i < text.length) {
    setTimeout(writeText, 150);
    allText += text[i];
    document.getElementById("screen").innerHTML = allText;
    i++;
  }
}

Example: https://codepen.io/petegivens/pen/VMxmXJ

Upvotes: 0

nnnnnn
nnnnnn

Reputation: 150030

The setTimout() function puts the function from its first argument on a queue to run later, it doesn't suspend execution of the current function. So before putText() is called from the first setTimeout() your entire for loop has finished and by then allText has the whole string.

Also, by specifying the delay of 150 in the loop you're queuing all of the functions to run 150ms from now, not 150ms between each other. Use 150 * (i+1) to multiply the delay by the loop counter.

One way to fix this is to use the fact that setTimeout() lets you specify arguments to be passed to your function. So modify putText() to accept an argument for what text to display, and then pass that value through as follows:

var text = 'Lorem ipsum dolor sit amet enim. Etiam ullamcorper.';

var allText = "";

function putText(text) {
  document.getElementById("screen").innerHTML = text;
}

function writeText() {
  for(i=0; i<text.length; i++){
    allText = allText + text[i];
    setTimeout(putText, 150 * (i+1), allText);
  };
}

window.onclick  = writeText;
<div id="screen">Click here to start typing.</div>

Should i use recursion, or maybe make something like "sleep" function?

You should never create a "sleep" function in the sense of a function that tries to pause execution of the current block, because that freezes the whole browser too.

You can implement the typing using a sort of pseudo-recursion with a function that calls setTimeout() to run itself again after a delay, maybe a little something like this:

function writeText(text) {
  var currentLetter = 1;
  function nextLetter() {
    document.getElementById("screen").innerHTML = text.slice(0, currentLetter);
    if (++currentLetter <= text.length)
      setTimeout(nextLetter, 150);
  }
  nextLetter();
}

var text = 'Lorem ipsum dolor sit amet enim. Etiam ullamcorper.';

window.onclick = function() { writeText(text); };
<div id="screen">Click here to start typing.</div>

Upvotes: 2

Related Questions