Reputation: 1095
I have just started learning JavaScript, coming from a Java/Clojure background and I am trying to do a simple thread-sleep command that will allow me to have lines of text appear on the screen, at one second intervals. I thought about using the setInterval
function instead, but because I am dealing with multiple functions, I thought setTimeout
would be better. The problem I am encountering is that all of the text is printing in the browser instantaneously, as though the setTimeout
functions weren't even there. Below is an example using the "Happy Birthday" song, which I think succinctly illustrates the problem. How can I make the program below run, line by line, at one second intervals?
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Happy Birthday</title>
</head>
<body>
<script>
var name = "Joe",
i = 0;
while (i < 2) {
setTimeout(document.write("Happy Birthday to you!<br>"), 1000);
i ++;
}
setTimeout(document.write("Happy Birthday dear " + name + ",<br>"), 1000);
setTimeout(document.write("Happy Birthday to you!<br>"), 1000);
</script>
</body>
</html>
Upvotes: 0
Views: 417
Reputation: 106385
To delay evaluation of some code, this code should be put into a function; that function reference should be passed into setTimeout
. For example:
setTimeout(function() {
document.write('Hello world!');
}, 1000);
As it stands, you evaluate document.write
expression instead immediately - that's why you see all the writings occurring simultaneously.
As a sidenote, please please please don't use document.write
unless you're really know what're you're doing. It's quite easy to 'log' something just by adjusting innerHTML
of log
element. For example:
<div id="log"></div>
<script>
var log = document.getElementById('log');
setTimeout(function() {
log.innerHTML += 'Hello world!<br />';
}, 1000);
</script>
Also, don't forget that each timeout is processed independently. To set up a chain of events, you'd manually increase the delay - otherwise all the functions will be called almost immediately after each other.
Overall, here's how it can be done:
<div id="log"></div>
<script>
var name = "Joe",
i = 0,
delayedMessage = function(msg) {
setTimeout(function() {
document.getElementById('log').innerHTML += msg;
}, ++i * 1000);
};
delayedMessage("Happy Birthday to you!<br>");
delayedMessage("Happy Birthday to you!<br>");
delayedMessage("Happy Birthday dear " + name + ",<br>");
delayedMessage("Happy Birthday to you!<br>");
</script>
Demo.
Upvotes: 2
Reputation: 1576
In your code you were executing the document.write and then setting the timeout handler with its return value which is clearly wrong.
Remember you must always pass a function (a handler) to every event you want to react to.
So, the correct code is:
setTimeout(function(){
document.write("Happy Birthday to you!<br>");
}, 1000);
Upvotes: 0