How to use split () and setTimeout () in javascript arrays

This can be a little confusing: S

If anyone can help me split the string array into letters. And than record it with timeouts. As in DOS.

I can do it with single strings, but I cannot do it in arrays.

Here is my code:

var text = new Array();
text[0] = "welcome ".split('');
text[1] = "how are u?".split('');
var delay = 20;
for (var j = 0; j < text.length; j++) {

    var txt = text[j];
    for (u = 0; u < txt.length; u++) {
        setTimeout(function () {
            $('div#console_div').append('<br />' + txt.shift());
        }, delay * j + 100);
    }
}

      

+3


source to share


2 answers


This is how I will do it. Instead of a loop, for

use a recursive function that calls itself with different arguments depending on where it is in the line (s):

var text = new Array();
text[0] = "welcome ".split('');
text[1] = "how are you?".split('');
var delay = 400;

function addOneChar(i, j) {
    $('#console_div').append('<br>' + text[i][j]);
    if (j+1<text[i].length) {  // next character in the current string
        setTimeout(function() { addOneChar(i, j+1); }, delay);
    } else if (i+1<text.length) {   // start the next string in the text[] array
        setTimeout(function() { addOneChar(i+1, 0); }, delay);
    } // else quit
}

setTimeout(function() { addOneChar(0,0); });

      

http://jsfiddle.net/mblase75/tkEDN/



We could simplify this by concatenating text[]

into one string and using .charAt()

to extract characters:

var text = new Array();
text[0] = "welcome ";
text[1] = "how are you?";
var delay = 400;
var textstr = text.join('');

function addOneChar(i) {
    $('#console_div').append('<br>' + textstr.charAt(i));
    if (i+1<textstr.length) {
        setTimeout(function() { addOneChar(i+1); }, delay);
    } // else quit
}

setTimeout(function() { addOneChar(0); });

      

http://jsfiddle.net/mblase75/MYtjy/

+3


source


You have a typical "loopback" problem. Check out JavaScript closures inside loops - a simple practical example . The timeout callbacks that are currently executing txt

refer to text[1]

. All timeouts are still being executed, so you call txt.shift()

more often than on an array.

Another problem is that any delay up to 100ms is hardly noticeable to anyone, so you don't see any increment. Worse, for the first phrase, all timeouts are executed at the same time (almost), since j

there is 0

and delay * j + 100

will result in 100

.




You are better off handling each letter one by one, rather than creating all the timeouts at once (note that Blazemonger's solution is the same, but easier to understand as it is cleaner).

var text = [...];

function printLetter(phrase_index, letter_index) {
    var word = text[phrase_index];
    if (word) {
        if (letter_index === word.length) {
            printLetter(phrase_index + 1, 0);
        }
        else {
            var letter = word[letter_index];
            if (letter) {
                $('div#console_div').append('<br />' + letter);
                setTimeout(function() {
                    printLetter(phrase_index, letter_index + 1);
                }, 200);
            }
        }
    }
}

printLetter(0, 0);

      

DEMO

+3


source







All Articles