0

I wrote this code in JS:

function startFunction() {
p1 = document.getElementById('p1').innerHTML;
for (var i=1; i<=p1.length; i++) {
        alert(p1.slice(0, i));
    }
}

I call the function with onload event in html:

    <body onload="startFunction()">

And thi is the paragraph with p1 id:

    <p id="p1">Hi, I'm</p>

How can I make a delay for the for loop. I want my program to write the p1 text letter by letter.

5
  • 2
    setTimeout(function(){},2000 /* time in ms */); Commented Nov 13, 2018 at 18:28
  • you should use either setTimeout or setInterval Commented Nov 13, 2018 at 18:28
  • Possible duplicate of Letter by letter animation with delay in loading Commented Nov 13, 2018 at 18:29
  • @devlincarnate dupes may exist, but dig up one without jQuery please. Commented Nov 13, 2018 at 18:30
  • @tevemadar - the gist of the answer isn't using jQuery. In fact, it's nearly identical to the first comment above. Commented Nov 13, 2018 at 18:32

5 Answers 5

1

You can not and should not delay anything inside a loop, because that is how the nonresponsive pages are made: the browser does not react to user actions or do anything visible until the JavaScript code returns.

Instead, you can use some timer, like setInterval():

function startFunction() {
    var p1 = document.getElementById('p1');
    var txt = p1.innerHTML;
    var i=0;
    var timer = setInterval(function() {
        p1.innerHTML = txt.slice(0,i++);
        if(i>txt.length) {
            clearInterval(timer);
        }
    },500);
}

startFunction();
<p id="p1">Hi, I'm</p>

Sign up to request clarification or add additional context in comments.

Comments

1
var alertEachLetter =function(p1, i){
    setTimeout(function(){
        alert(p1.slice(0, i));
    },1000);
};

 function startFunction() {
 p1 = document.getElementById('p1').innerHTML;
 for (var i=1; i<=p1.length; i++) {
        alertEachLetter(p1, i);
    }
}

why create this alertEachLetter function. for that you need to check this link

setTimeout in for-loop does not print consecutive values

Comments

1

You don't need a loop, you need an interval. Javascript's interval feature will call your function at (approximately) the requested interval. So, for example:

function startFunction() {
  var p1 = document.getElementById('p1').innerHTML
  var count = 1
  var finished = p1.length
  var iv = setInterval(function() {
    alert(p1.slice(0,count++))
    if (count > finished) {
      clearInterval(iv) // stops the interval from firing once we finish our task
    }
  }, 1000) // 1000 ms, or every second.
}

Comments

1

Here's a quick example using setTimeout instead of setInterval. There's not much difference except you don't have to clear the timeout - you simply don't run it if it doesn't meet a condition.

// cache the elements
const p1 = document.getElementById('p1');
const out = document.getElementById('out');

// make the text content from p1 iterable and split it into
// the head (first element), and tail (everything else)
const [head, ...tail] = [...p1.textContent];

const loop = function loop(head, tail) {

  // update the output text content with the result of head
  out.textContent = head;

  // if there's anything left of the tail array
  if (tail.length) {

    // remove the first element of tail and
    // add it to head
    head += tail.shift();

    // call the function again with the new head and tail
    setTimeout(loop, 200, head, tail);
  }

// pass in the head and tail to the function
}(head, tail);
#p1 { display: none; }
<p id="p1">Content written letter by letter</p>
<p id="out"></p>

Comments

0

Below is an approach I think may help you achieve what youre trying to do. This approach uses setInterval (instead of a loop) to execute a function multiple times. See the comments to understand the code logic:

//Grab our DOM elements
var p1 = document.getElementById('p1').innerHTML;
var copy = document.getElementById('copy');

//Execute a function every 250 milliseconds
var intervalId = setInterval(onInterval, 250);

//nextLetter is a function that will return the character at a particular index in the string. The function will increase the index each time it is called. The function will return null once it exceeds the innerHTML length. c is a "private" variable that can't be modified elsewhere in the program.
var nextLetter = (function(i, limit) {
  var c = i;
  return function() {
    var idx = c++;
    if (idx > limit) {
      return null;
    }
    return p1.charAt(idx);
  };
})(0, p1.length);

//The function we will execute at each interval
function onInterval() {
  var letter = nextLetter();
  if (letter) {
    copy.innerHTML += letter;
  } else {
    console.log('End of content reached - removing interval');
    clearTimeout(intervalId);
  }
}
<p id="p1">Make sure to read the in-code comments</p>
<p id="copy"></p>

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.