0

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.

2

3 Answers 3

1

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);

Example

Another formate:

    var i = 0;
    var timer = setInterval(function () {
        children[i].style.display = "block";
        i++;
        if (i == children.length) {
            clearInterval(timer);
        }
    }, 2000);

EXAMPLE

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.

Sign up to request clarification or add additional context in comments.

4 Comments

The images are shown but all at once. The point is that there is 2 seconds delay for the next image to appear.
Yeah, iv'e been looking forward to that
@Johnny Oh yes, sorry.
@Johnny Check out the edit. I suggest just using a setInterval
1

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);
        }

Check Fiddle

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.

1 Comment

The images are shown but all at once. The point is that there is 2 seconds delay for the next image to appear.
1

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;
}

3 Comments

The second example works perfectly. The first one trows error <code>Uncaught ReferenceError: i is not defined </code>. Nice idea with that hideElement function. BTW. Last example should be 'block' instead of 'none' ;]. Thanks!
Yeah with the first one it still has to be in the loop.
Now both are working! Good idea with the anonymous function, simple and effective.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.