'Javascript - Delay, Pause, Sleep -- WHERE ARE YOU? + Changing iFrame's SRC with Array
I'm having problems with setTimeout. I've also tried setInterval. I wish JS just had a pause or sleep.
In theory, this code should write the first link from the array, wait 3 seconds, write the next, and so on. But it won't even call the function.
<html>
<head></head>
<body>
<a href="http://www.google.com">Google</a>
<a href="http://www.thinkgeek.com">ThinkGeek</a>
<a href="http://www.themetapicture.com">The Meta Picture</a>
<iframe src="http://www.google.com" id="myid" name="main" width="1024" height="768">
</iframe>
<script>
function getLinksArray(){
for(var i=0; i < document.links.length; i++){
var linx = document.links[i].href;
setTimeout("openLinks(linx)"),3000);
}
}
function openLinks(link){
document.write(link + "<br />");
}
window.onload = getLinksArray();
</script>
</body>
</html>
The second part of my question is to change the src of the iframe to the links (instead of writing them). I'm only using the document.write for testing purposes to get the delay working.
I've tried document.getElementById("myid").src = link; and it won't do anything at all. Almost as if the iframe doesn't even exist.
I'm not a pro, so I'm here hoping to get help from a pro. ;) Thanks in advance.
Solution 1:[1]
First, never, ever, pass a string to setTimeout.
// old and busted
setTimeout("openLinks(linx)"),3000);
// new hotness
setTimeout(function() {
openLinks(linx)
}, 3000);
Second, loops that generate functions need some additional help. You need to capture the value of the loop in a closure, otherwise the value will change before the function that uses it executes.
function getLinksArray() {
for (var i = 0; i < document.links.length; i++) {
var linx = document.links[i].href;
// create a closure for each loop iteration
(function(linx) {
setTimeout(function() {
openLinks(linx);
}, 3000);
}(linx));
}
}
function openLinks(link) {
// document.write(link + "<br />");
// document.write is also bad for a number of reasons
someElement.innerHTML += link + "<br />"
}
window.onload = getLinksArray();
What that closure magic does is create brand new local variable shared only with the function created on each iteration of the loop. Without it you actually have something that looks more like this:
var linx; // var linx in the loop actually get hoisted to outside the loop!
for(var i=0; i < document.links.length; i++){
linx = document.links[i].href;
setTimeout(function() {
openLinks(linx)
},3000);
}
}
Looking at that, you can see that the loop will be done running, linx will be set the last value of that loop, and then your first timeout will fire using the value of linx that all the timeouts share.
Creating and executing a function, passing in that value prevents that hoisting and sharing.
Solution 2:[2]
You're mostly having problems because you can't call setTimeout like that.
You should pass a function, which will need to be passed a bound variable, i.e.
for (var i=0; i < document.links.length; i++) {
var linx = document.links[i].href;
setTimeout(function(linx) {
return function() {
openlinks(linx);
}
}(linx),3000);
}
The inner stuff is one of the "standard" Javascript ways of passing a loop variable to a callback. If it doesn't make sense, you're gonna need a lot more help...
Solution 3:[3]
thanks to everyone's help I have a final working product:
<html>
<head></head>
<body>
<a href="http://www.google.com">Google</a><br />
<a href="http://www.thinkgeek.com">ThinkGeek</a><br />
<a href="http://www.themetapicture.com">The Meta Picture</a>
<iframe src="http://www.google.com" id="myid" name="main" width="1024" height="768">
</iframe>
<script>
function getLinksArray() {
for (var i = 0; i < document.links.length; i++) {
var linx = document.links;
(function loadLink(i) {
setTimeout(function () {
document.getElementById("myid").src = linx[i].href;
if(linx[++i])
{
loadLink(i);
}
}, 20000)
})(0);
}
}
window.onload = getLinksArray();
</script>
</body>
</html>
Solution 4:[4]
To pause for 1 second in async function you can simply use:
await new Promise(_ => setTimeout(_, 1000));
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | |
| Solution 2 | Alnitak |
| Solution 3 | Will |
| Solution 4 | Zuhair Taha |
