2013-05-29 2 views
2

У меня есть несколько divs, которые я хочу показать последовательно. Я пробовал:Могу ли я последовательно исчезать divs с помощью цикла?

var divs = ["#masterhead", ".links", ".code", ".projects", ".self"] 
var fade_time = 1000; 
var pause_time = 500; 
for(var i = 0; i <= divs.length; i = i + 1) 
{ 
    setTimeout(divs[i].fadeIn(fade_time) , 500) ; 
} 

Я пытался, потому что я хотел более короткий код, в отличие от (который работает так, как я хочу его):

function A() 
    { 
     jQuery("#masterhead").fadeIn(fade_time); 
     setTimeout(B, 500); 
    } 
    function B(){ 
     jQuery(".links").fadeIn(fade_time); 
     setTimeout(C, 500); 
    } 

    function C(){ 
     jQuery(".code").fadeIn(fade_time); 
     setTimeout(D, 500); 
    } 
    function D(){ 
     jQuery(".projects").fadeIn(fade_time); 
     setTimeout(E, 500); 
    } 

    function E(){ 
     jQuery(".self").fadeIn(fade_time); 
    } 
    A(); 

Итак, что я делаю неправильно в более короткий код ?

+3

Вы понимаете, что 'divs [i]' - это просто строка, а не элемент HTML или узел DOM? –

+0

Я действительно считал это, но я новичок и действительно не знал, что искал, чтобы исправить это. –

+0

Не могли бы вы показать (маленькую) [живую демонстрацию] (http://jsfiddle.net/), которая воспроизводит вашу проблему/страницу? –

ответ

3

Вот более простой способ сделать это, не использующую setTimeout() вообще; JQuery-х .delay() method понятнее для этой цели:

for(var i = 0; i < divs.length; i = i + 1) 
{ 
    $(divs[i]).delay(pause_time * i).fadeIn(fade_time); 
} 

Демо: http://jsfiddle.net/sK99B/

Четыре проблемы с вашим кодом:

  • divs[i] содержит селектор в виде строки, поэтому вам нужно использовать $(divs[i]), чтобы получить объект jQuery, который вы можете назвать .fadeIn().
  • setTimeout() ожидает, что функция станет ее первым параметром. Вы пытаетесь вызвать функцию напрямую. Вы можете исправить это, обернув его анонимной функцией.
  • setTimeout() не приостанавливает выполнение, он ставит в очередь функцию для запуска позже, поэтому, поскольку все ваши тайм-ауты установлены на 500, все они будут стоять в очереди, чтобы работать (практически) в одно и то же время.
  • Условие в вашем for должно использовать <, а не <=.

Try:

for(var i = 0; i < divs.length; i = i + 1) 
{ 
    (function(i){ 
     setTimeout(function() { $(divs[i]).fadeIn(fade_time); }, pause_time * i); 
    })(i); 
} 

Демо: http://jsfiddle.net/sK99B/1/

Обратите внимание, что если функция передается setTimeout() использует счетчик i цикла вы будете иметь проблему, потому что функции не будут работать не до после окончания цикла они все попытаются использовать конечное значение i - поэтому вам нужно ввести закрытие, что делает этот метод еще более беспорядочным.

+0

Все ответы работают, но я рад, что вы это объяснили. Благодарю. –

5

Использовать обратный вызов.

var divs = ["#masterhead", ".links", ".code", ".projects", ".self"] 
var fade_time = 1000; 
var pause_time = 500; 
var i = 0; 
function startDisplay() { 
    i = 0; 
    showNext(); 
} 
// just use this function as a callback, each time, to display the next 
function showNext() { 
    if (!divs[i]) { 
    // dernière div 
    return 
    } 

    setTimeout(function() { 
    // you can hide the previous one, for example 
    //$(divs[i-1]).hide(); 
    // take the current div, increment it 
    $(divs[i++]) 
     // fade it in, and use the current function as callback 
     .fadeIn(fade_time, showNext); 
    }, pause_time); 
} 
1

Попробуйте это -

for(var i = 0; i <= divs.length; i = i + 1){ 
    setTimeout(function(){ 
     $(divs[i]).fadeIn(fade_time); 
    } , 500 + (i*pause_time)) ; 
} 
+0

Это вызовет '.fadeIn()' немедленно и передаст его возвращаемое значение 'setTimeout()' ... – nnnnnn

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