2013-07-19 3 views
0

Этот код должен переключать свойство отображения всех дочерних элементов # слайд-контейнера на «блокировку» с задержкой по времени между переключателями с задержкой по времени.Неопределенная переменная JavaScript в анонимной функции

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

Я использую его вместе с этим 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> 

Я получаю ошибку Uncaught TypeError: Cannot read property 'style' of undefined

Он говорит, что не может найти детей или детей [0]. Но эта переменная указана и существуют dom-узлы.

+2

Отметьте здесь http://stackoverflow.com/questions/1451009/javascript-infamous-loop-problem – elclanrs

+0

Возможный дубликат [Закрытие Javascript внутри петель - простой практический пример] (http://stackoverflow.com/questions/750486/javascript-clos-inside-loops-simple-practice-example) –

ответ

1

Закрытие вопрос.
Попробуйте добавить 3-ий параметр в SetTimeout (не работает):

setTimeout(function(i){ 
    children[i].style.display = "block"; 
    console.log(i); 
}, 2000, i); 

Example

Другой формиат:

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

EXAMPLE

ES6 вокруг угла, инструкция let специально построена для таких ситуаций:

for (let i = 0; children.length > i; i++) { 
    setTimeout(function(){ 
     children[i].style.display = "block"; 
     console.log(i); 
    }, 2000); 
} 

Однако это не тот ответ, который вам нужен прямо сейчас. Это было всего лишь запиской.

+0

Изображения отображаются, но все сразу. Дело в том, что для появления следующего изображения есть 2-секундная задержка. – Johnny

+0

Да, я с нетерпением ждал этого – iConnor

+0

@Johnny О да, извините. – Shawn31313

1

Попробуйте заключени в SetTimeout в IIFE (Сразу вызывается выражение функции)

for (var i = 0; children.length > i; i++) { 
     (function (index) { 
       setTimeout(function() { 
        children[index].style.display = "block"; 
        console.log(i); 
       }, 2000); 
      })(i); 
     } 

Check Fiddle

Обращение i является общим для всех функций, выполняемых setTimeout. Таким образом, к моменту выполнения функции внутри значение i будет указывать на children.length.

Но нет элемента, который ссылается на children[children.length], которого нет и выдает ошибку.

+0

Изображения отображаются, но все сразу. Дело в том, что для появления следующего изображения есть 2-секундная задержка. – Johnny

1

К тому времени setTimeout готов i будет длина children, так что вы должны захватить значение i

попробовать этот

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

или вы могли бы сделать это. ... Я исправил задержку вещь

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

Второй пример отлично работает.Первая из них вызывает ошибку Uncaught ReferenceError: i is not defined. Хорошая идея с этой функцией hideElement. КСТАТИ. Последний пример должен быть «block» вместо «none»;]. Благодаря! – Johnny

+0

Да, с первым он все еще должен быть в цикле. – iConnor

+0

Редактировать - 1-й пример – iConnor

Смежные вопросы