Surak
Surak

Reputation: 23

I need a delay that isn't setTimeout()

This is the code that I have and I want to make it so that the letters (sentence parameter) type themselves one by one. Not all at a time. I keep trying with setTimeout() but I can't do it so that it keeps it's progress. Please help.

var letters = [];

function typeOut(sentence, code) {
    $('body').append('<p id=' + code + '></p>');


    for (i = 0; i < sentence.length; i++) {
        letters[i] = sentence[i];
        $('#' + code).append(letters[i]);
    }
}

typeOut("Hello World", 1);

Thanks in advance!

Upvotes: 2

Views: 87

Answers (5)

Alex Kudryashev
Alex Kudryashev

Reputation: 9460

Why nobody remember that setTimeout accepts more than two arguments? It is very convenient feature. This is my version of typeOut.

function typeOut(text) {
    var out = document.getElementById('out');
    out.innerHTML = '';
    setTimeout(function typeNext(i) { //internal function can be named
        out.innerHTML += text[i++];
        if (i < text.length)
            setTimeout(typeNext, 100, i);
    }, 100, 0); //3rd arg goes to the function
}
<p id="out"></p>
<button type="button" onclick="typeOut('Hello World');">Type Out</button>

Upvotes: 0

adeneo
adeneo

Reputation: 318202

There really aren't that many options, the only thing suitable for this is timers, either setTimout or setInterval.

You could always use jQuery's delay() method, but internally it also uses setTimeout

function typeOut(sentence, speed) {
    var p = $('<p />'), i = 0;
    $('body').append(p);
    
    (function go() {
        p.dequeue().append(sentence[i++]).delay(speed).queue(go);
    })();
}

typeOut("Hello World", 1000);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

Upvotes: 0

Louys Patrice Bessette
Louys Patrice Bessette

Reputation: 33933

I had fun with this question....
I may have done a little more than you asked.
But I think you will like it.

See in this CodePen.

My version of your typeOut function:

function typeOut(sentence, code) {
    $('body').append('<p id=' + code + '></p>');

    var i=0;
    var letterDelay = setInterval(function(){
        $('#' + code).append(sentence[i]);
        i++;
    }, $("#speed").val() );
}

Upvotes: 1

Oriol
Oriol

Reputation: 288130

setTimeout seems perfect. I guess you are using it incorrectly.

function typeOut(sentence) {
  var txt = document.body
    .appendChild(document.createElement('p'))
    .appendChild(document.createTextNode(''));
  var i = 0;
  (function typeLetter() {
    if(i < sentence.length) {
      txt.nodeValue += sentence[i];
      ++i;
      setTimeout(typeLetter, 100);
    }
  })();
}
typeOut("Hello World");

Upvotes: 3

Abdelrahman M. Allam
Abdelrahman M. Allam

Reputation: 922

There is many way to make this work could this solution for you work to

 var letters = [];

function typeOut(sentence, code) {
    $('body').append('<p id=' + code + '></p>');
    self = this;
    self.currentIndex = 0;
    self.sentence = sentence;
    
	  var write =  function (){
    	if(self.currentIndex < sentence.length) {
          letter = sentence[self.currentIndex];
          $('#' + code).append(letter);
           self.currentIndex+=1;
    	}else {
          clearInterval(self.writeHandler);
        }
    }
    
    self.writeHandler = setInterval(write, 500)
}

typeOut("Hello World", "div1");
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<p id="div1"></p>

here on jsbin check this

Upvotes: 0

Related Questions