Reputation: 15
Struggling on a for loop.. I cant seem to make it work..Trying to add a for loop to the (".circle" + (i+1)) Selector but not hiding and fading in one circle(i). Is this possible or some similar approach?
Any help would be appreciate it!
<!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>
Upvotes: 0
Views: 1347
Reputation: 11072
Matt Burland's answer is correct and very thorough. This is merely an alternate suggestion to avoid using the for
loop (if you prefer):
// Use the jQuery's already-available `.each` method
$(".menu li").each(function(index, list_element){
(function(list_index){ // as per Matt's answer
list_element.on('click',function(){
$(".circle").hide();
$('.circle'+(list_index+1)).stop().fadeIn('300');
return false;
}
})(index);
});
The effect is the same, and there is no performance difference (so far as I know); I find it slightly cleaner.
Upvotes: 0
Reputation: 45135
Your problem is with the way variables are scoped. i
will always have the value that it had at the end of the loop in your click handler. You can fix it like this:
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);
}
What the above does is create a closure by using an Immediately Invoked Function Expression (IIFE) that creates a new scope and copies the value of i
during the loop.
It would also be assign $(".menu li").length
to a variable before the loop so that jQuery isn't recreating the collection every time it loops.
To understand what's going on, compare this:
for(i=0;i<5;i++){
setTimeout(function() {
console.log(i);
},100);
}
// outputs: 5 5 5 5 5
To this:
for(i=0;i<5;i++){
(function(i) {
setTimeout(function() {
console.log(i);
},100);
})(i);
}
// outputs: 0 1 2 3 4
Upvotes: 4