Writing effect using javascript, setInterval does not work

Asked

Viewed 614 times

4

I’m trying to use the setInterval function to write 1 letter every second, but it didn’t work:

partText = "";

function escrever(text) {   
    for (i = 0; i < text.length; i++) {
        partText += (text.charAt(i));   
        document.getElementById("texto").innerHTML = partText;
    }
}

setInterval(escrever("teste"), 1000);

4 answers

3

You can do it like this:

function escrever(text) {
    var el = document.getElementById("texto");
    for (i = 0; i < text.length; i++) {
        setTimeout(function(letra) {
            el.innerHTML += letra;
        }, 1000 * i, text[i]);
    }
}
escrever('teste');
<div id="texto"></div>

jsFiddle: https://jsfiddle.net/y18afv4t/

To be taken into account:

  • uses += to add HTML. Only = will replace everything
  • avoids document.getElementByID within the for, this is heavy for the browser. Cache as I did in the example.

2


Error is in two parts:

1 setInterval.

setInterval(escrever("teste"), 1000);

the correct is

setInterval(function(){escrever("teste")}, 1000);

2 Loop of repetition.

for (i = 0; i < text.length; i++)

Here he will always write everything in the text

Below the changes:

partText = "";
var index=-1;
function escrever(text) {   

    index++;

    if(index<text.length){    
      partText += (text.charAt(index));   
      document.getElementById("texto").innerHTML = partText;
    }  
    else
    {
      clearInterval(timer);
    }

  }

var timer= setInterval(function(){escrever("teste")}, 1000);

Example|jsfidlle

  • I find it unnecessary to have a global variable just to save the .charAt In that case it would be nice to have a variable for document.getElementById("texto"), thus avoiding to always go to the GIFT to get it. Together also var to partText not to export to the global space.

2

The setInterval may not be a good one because it repeats indefinitely (until it is determined that it stops with clearInterval). What I recommend is that you use setTimeout that runs only once.

With that, your code would look something like this:

var partText = "";
function escreverNoObjeto (objeto, texto) {
    objeto.innerHTML = texto;
}

function escrever(text, intervalo) {
    var partText = '';
    var fn = function(texto) {
        return function() {
            /* pode ser document.getElementById("texto")*/
            escreverNoObjeto(document.body, texto);
        };
    };

    for (i = 0; i < text.length; i++) {
        partText += text.charAt(i);

        setTimeout(fn(partText), intervalo * (i + 1));
    }
}

escrever("teste", 1000);

You can still see it working on Jsfiddle

I hope I helped the/

  • Are you declaring var partText = ""; twice, I think it was forgetfulness, right? It would be good to cache the DOM object outside of fn which is called n times.

1

The parameters are not passed as you are doing:

Try:

setInterval(escrever, 1000, 'test');

Example in jsfiddle.

I don’t know if that’s what you want but so the impression of each letter is instantaneous, only in the whole str.

To make letter to letter:

...
<p id="texto"></p>
...

var testStr = 'Vamos lá escrever isto';
function escrever(i) {
    partText = testStr.charAt(i);   
    document.getElementById("texto").innerHTML += partText;
    i += 1;
    if(i < testStr.length) {
        setTimeout(escrever, 400, i); // timing entre cada impressão aqui
    }
}

index_da_letra = 0;
escrever(index_da_letra);

Example in jsfiddle:

  • That function escrever is called eternally... when it stops?

Browser other questions tagged

You are not signed in. Login or sign up in order to post.