Борясь с циклом for... Я не могу заставить его работать. Попытайтесь добавить цикл for к элементу (".circle" + (i + 1)), но не скрывать и исчезать в одном круге (i). Возможно ли это или какой-то подобный подход?
Любая помощь была бы оценена!
<!DOCTYPE html>
<html>
<head>
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
</head>
<body>
<ul class="menu">
<li class="first"><a href="#btn1">btn1</a></li>
<li class="second"><a href="#btn2">btn2</a></li>
<li class="third"><a href="#btn3">btn3</a></li>
<li class="forth"><a href="#btn4">btn4</a></li>
</ul>
<div class="circle1 circle">1</div>
<div class="circle1 circle">2</div>
<div class="circle1 circle">3</div>
<div class="circle4 circle">4</div>
<script>
for(i=0;i<$(".menu li").length;i++){
$(".menu li").eq(i).on('click',function(){
$(".circle").hide();
$('.circle'+(i+1)).stop().fadeIn('300');
return false;
});
}
</script>
</body>
</html>
Ваша проблема связана с тем, как изменяются переменные. i
всегда буду иметь значение, которое было в конце цикла в вашем обработчике кликов. Вы можете исправить это следующим образом:
for(i=0;i<$(".menu li").length;i++){
(function(j) {
$(".menu li").eq(j).on('click',function(){
$(".circle").hide();
$('.circle'+(j+1)).stop().fadeIn('300');
return false;
});
})(i);
}
То, что было сделано выше, создает замыкание с помощью Expression Expression Expression (IIFE), которое создает новую область и копирует значение i
во время цикла.
Также было бы назначить $(".menu li").length
переменной перед циклом, чтобы jQuery не воссоздавал коллекцию каждый раз, когда она циклы.
Чтобы понять, что происходит, сравните это:
for(i=0;i<5;i++){
setTimeout(function() {
console.log(i);
},100);
}
// outputs: 5 5 5 5 5
К этому:
for(i=0;i<5;i++){
(function(i) {
setTimeout(function() {
console.log(i);
},100);
})(i);
}
// outputs: 0 1 2 3 4
Ответ Мэтта Берланда правильный и очень тщательный. Это просто альтернативное предложение избегать использования цикла for
(если вы предпочитаете):
// Use the jQuery already-available '.each' method
$(".menu li").each(function(index, list_element){
(function(list_index){ // as per Matt answer
list_element.on('click',function(){
$(".circle").hide();
$('.circle'+(list_index+1)).stop().fadeIn('300');
return false;
}
})(index);
});
Эффект тот же, и нет разницы в производительности (насколько я знаю); Я нахожу его немного чище.
i
всегда равен его значению в конце цикла в вашем обработчике кликов.