0

Trying to debug the following code

function split(toRead, toReplace, speed) {
    var words = $(toRead).html().split(" ");
    for (var i = 0; i < words.length; i++) {
        //console.log(words[i]);
        setTimeout(function () {
            $(toReplace).html(words[i]);
        }, speed * i);
    }
}

The code should receive a block of text 'toRead', break it down to words, and then replace 'toReplace' with each word, with a set time interval. Like http://www.spreeder.com/ does.

However, it doesn't seem to work. I'm guessing this has something to do with the timing and the for loop (Seems like the for loop ends regardless of the timer, making words[i] read the same word every time).

Really appreciate any help, thanks guys & gals :) Cheers, Nir

Nir Benita
  • 511
  • 1
  • 7
  • 12
  • and [Passing functions to setTimeout in a loop: always the last value?](http://stackoverflow.com/q/6425062/218196) and [setTimeout in a for-loop and pass i as value](http://stackoverflow.com/q/5226285/218196) (both found via [`[javascript] settimeout loop`](https://stackoverflow.com/search?q=[javascript]+settimeout+loop)). – Felix Kling Feb 25 '14 at 08:23

2 Answers2

0

Try using this:

<!DOCTYPE html>
<html>
<head>
<script type="text/javascript" src="jquery.js"></script>
</head>
<body>
<div id="toRead">This is a sample text do demonstrate that the code below works fine. Please test this code and vote up if it works for you !!</div>
<div id="results"></div>
<script type="text/javascript"> 
var ctr=0;
function displayWords(words,len,toReplace,speed){
    if(ctr<len){
        setTimeout(function(){
            $(toReplace).html(words[ctr]);
            ctr++;
            displayWords(words,len,toReplace,speed);
        },speed);
    }
}

function split(toRead, toReplace, speed) {
    var words = $(toRead).html().split(" ");
    displayWords(words,words.length,toReplace,speed);
}

split(document.getElementById("toRead"),document.getElementById("results"),200);
</script>
</body>
</html> 

Explanation: When you use setTimeout inside a for loop, the JavaScript engine does not delay the code execution and wait for the timeout.

So, the correct approach is to use a recursive function and then check if the count has not been reached then again call the same function. continue this till the count is reached. This way you can have your desired functionality.

kcak11
  • 832
  • 7
  • 19
  • Your answer would be more useful if you also **explained** your solution. What did you do and why? – Felix Kling Feb 25 '14 at 08:57
  • 1
    @FelixKling I have added the explanation to the code above. – kcak11 Feb 25 '14 at 09:03
  • Why -1 to my answer ? I have tested the code and exactly works the way www.spreeder.com works. Whats the issue then ? – kcak11 Feb 25 '14 at 09:37
  • Thanks, that indeed solves my question. But I'm pretty bummed since there's no way I'd ever figure this out on my on... Just a depressed designer here, no wories :P Thanks again! – Nir Benita Feb 25 '14 at 18:27
0

You probably want to append to the toReplace DIV's content. In your question you just change it's content as shown below

$('#toReplace').html(words[i]);

If you want to append you should do

$('#toReplace').html().append(" " + words[i]);

Please notice that $('#toReplace') is used instead of $(toReplace) - this means that you want to target an element with the ID toReplace.

However if you pass the elements directly in to the method, as you do, you should use directly

toReplace.html(words[i]); // and so on.. don't use $(toReplace)
Dropout
  • 13,653
  • 10
  • 56
  • 109
  • The question was about displaying individual words with a delay. user has mentioned the sample www.spreeder.com – kcak11 Feb 25 '14 at 09:21
  • Ah, ok then. Anyway the answer to the problem is designated by the bold text. Thanks for the notice though. – Dropout Feb 25 '14 at 09:21