This code is supposed to switch the display property of all children elements of #slide-container to "block" with time delay two seconds between the switches.
var magic = window.setInterval(function(){
if (document.readyState === "complete") {
var children = document.getElementById('slide-container').children;
for (var i = 0; children.length > i; i++ ) {
setTimeout(function(){
children[i].style.display = "block";
console.log(i);
},2000);
}
magic = window.clearInterval(magic);
} else {
console.log("...");
}
}, 1000);
I am using it along with this html:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<title></title>
<meta name="description" content="">
<meta name="viewport" content="width=device-width">
</head>
<body>
<ul id="slide-container">
<li style="display: none;"><img src="http://i.imgur.com/8qBcyzc.jpg"></li>
<li style="display: none;"><img src="http://i.imgur.com/oxMTFTF.png"></li>
<li style="display: none;"><img src="http://i.imgur.com/JTM6Yqg.jpg"></li>
</ul>
</body>
</html>
I get error Uncaught TypeError: Cannot read property 'style' of undefined
It says it cannot find children or children[0]. But that variable has been specified and the dom nodes exist.
Try encasing the setTimeout in an IIFE (Immediately invoked function expression)
for (var i = 0; children.length > i; i++) {
(function (index) {
setTimeout(function () {
children[index].style.display = "block";
console.log(i);
}, 2000);
})(i);
}
The reference of i
is common to all the functions executed by setTimeout
. So by the time the function inside executes , the value of i
will point to children.length
.
But there is no element that refers to children[children.length]
which does not exist and throws an error.
By the time setTimeout
is ready i
will be the length of children
so you have to capture the value of i
try this
var time = 2000;
for (var i = 0; children.length > i; i++ ) {
(function( child, time) {
window.setTimeout(function() {
child.style.display = "block";
}, time);
}( children[i], time));
time += 2000;
}
or you could do this. ... I have fixed the delay thing
var hideElement = function( element, time) {
window.setTimeout(function() {
element.style.display = 'block';
}, time);
};
var time = 2000;
for (var i = 0; children.length > i; i++ ) {
hideElement(children[i], time);
time += 2000;
}
Closure issue.
Try adding a 3rd parameter to the setTimeout (doesn't work):
setTimeout(function(i){
children[i].style.display = "block";
console.log(i);
}, 2000, i);
Another formate:
var i = 0;
var timer = setInterval(function () {
children[i].style.display = "block";
i++;
if (i == children.length) {
clearInterval(timer);
}
}, 2000);
ES6 is around the corner, the let
statement is especially built for situations like this:
for (let i = 0; children.length > i; i++ ) {
setTimeout(function(){
children[i].style.display = "block";
console.log(i);
}, 2000);
}
However this is not the answer you need for right now. This was just a note.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.