2015-11-16 4 views
0

У меня есть код:экв :() не работает должным образом

 $("#button").click(function() { 
      for (var i = 0; i < 4; i++) { 
       setTimeout(function() { 
        $(".rows:eq("+i+")").css("background-color", "blue"); 
       },500); 
      } 
     }); 

По какой-то причине только пятый элемент получает фон-серый цвет. Что не так?

+1

уход поставить HTML – jstuartmilne

+1

Когда ваша первая функция таймаута выполнил, 'i' уже был увеличен до 4. Поместите цикл' for' в функцию таймаута. –

+0

вам нужно использовать закрывающее устройство –

ответ

2

Это связано с областью определения переменной i. Он привязан к циклу for, а не к функции, вызываемой setTimeout. В основном, когда вызывается функция задержки, i уже имеет приращение до 4. Чтобы связать текущее значение цикла i, вызовите другую функцию. i помещается в стек функций, поэтому значение сохраняется.

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

$("#button").click(function() { 
    setTimeout(function(){ 
    for (var i = 0; i < 4; i++) { 
     $(".rows:eq("+i+")").css("background-color", "blue"); 
    } 
    ,500); 
}); 

В противном случае попробуйте:

bindItoFunc = function (i) { 
    return function(){ 
    $(".rows:eq("+i+")").css("background-color", "blue"); 
    }; 
} 
$("#button").click(function() { 
    for (var i = 0; i < 4; i++) { 
    setTimeout(bindItoFunc(i),500); 
    } 
}); 

Может быть, более элегантное решение, чтобы связать i как this значение функции.

bindItoFunc = function() { 
    $(".rows:eq("+this+")").css("background-color", "blue"); 
} 
$("#button").click(function() { 
    for (var i = 0; i < 4; i++) { 
    setTimeout(bindItoFunc.bind(i),500); 
    } 
}); 

Вопрос спросил, что фон должен меняться по порядку. В этом случае измените waitM на основе i.

bindItoFunc = function() { 
    $(".rows:eq("+this+")").css("background-color", "blue"); 
} 
$("#button").click(function() { 
    for (var i = 0; i < 4; i++) { 
    setTimeout(bindItoFunc.bind(i),500+(100*i)); 
    } 
}); 
+0

Оба решения делают все синие div одновременно. Мне нужно сделать их синими по порядку. – WhilseySoon

+0

Я обновил ответ, проверьте последний пример. Это то, чего вы хотите достичь? –

+0

Да, спасибо. – WhilseySoon

0

Попробуйте использовать .delay(), .queue(), рекурсивный вызов click обработчик с увеличенным .index() из .row в качестве параметра после первоначальной установки .eq() в event.data: 0

// `0` : `event.data` 
 
$("#button").click(0, function re(event) { 
 
    var i = typeof event.data === "number" ? event.data : event; 
 
    $(".row").eq(i).delay(500).queue(function() { 
 
    $(this).css("background-color", "blue"); 
 
    if ($(this).index(".row") < 3) { 
 
     re(i + 1) 
 
    } 
 
    }) 
 
})
.row { 
 
    color:orange; 
 
    width:36px; 
 
    padding:8px; 
 
    font-weight:bold; 
 
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"> 
 
</script> 
 
<button id="button">click</button> 
 
<span class="row">0</span> 
 
<span class="row">1</span> 
 
<span class="row">2</span> 
 
<span class="row">3</span> 
 
<span class="row">4</span>

+0

Зачем нам это нужно? 'var i = typeof e! ==" number "? 0: e; ' – WhilseySoon

+0

@Somaroton' e' будет 'event' объектом' click' в функции обработчика при первом вызове 're'. Другой вариант - передать данные в обработчик кликов. – guest271314

+0

@Somaroton См. Обновленное сообщение для реализации с использованием 'event.data' – guest271314

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