Reputation: 385
sorry this may be a simple question. I am trying to build my first navigation using jQuery. The idea is that on hover of the button that the background colour and text colour changes as long as it is not the 'selected' button. I have all this working fine apart from the text colour. As in the jQuery it cannot see my loop variable:
function testIndex(navIndex){
for(i=0; i<=4; i++){
if(i != navIndex){
$('#nav a:eq('+i+')').hover(function(){
$(this).fadeTo('fast', 0.3, function(){
$(this).css('background-color','#ff3520');
$('#nav li:eq('+i+')').css('color', '#ffffff');
}).fadeTo('fast', 1);
},
function(){
$(this).fadeTo('fast', 0.3, function(){
$(this).css('background-color', '#e8e8e8');
$('#nav li:eq('+i+')').css('color', '#ff3520');
}).fadeTo('fast', 1);
});
};
};
};
On the
$('#nav li:eq('+i+')').css('color', '#ff3520');
The 'i' variable cannot be seen. I've tested it by inserting my own variables and it works.
Any advice?
Thanks.
Upvotes: 2
Views: 101
Reputation: 816334
It has already been explained what the problem with your code is (scope of i
) and solutions have been provided. Also have a look at this related question: JavaScript closure inside loops – simple practical example.
However you can solve it differently, not using an index at all but using DOM traversal, in a more jQuery-oriented way. I assume your HTML looks similar to this:
<ul id="#nav">
<li><a>...</a></li>
<li><a>...</a></li>
</ul>
i.e. the a
elements are descendants of the li
you want to change.
You can then achieve the same with the following code:
function testIndex(navIndex){
$('#nav a').slice(0,5).not(function(i) {
return i === navIndex;
}).hover(function(){
$(this).fadeTo('fast', 0.3, function(){
$(this).css('background-color','#ff3520')
.closest('li').css('color', '#ffffff');
}).fadeTo('fast', 1);
}, function(){
$(this).fadeTo('fast', 0.3, function(){
$(this).css('background-color', '#e8e8e8');
.closest('li').css('color', '#ff3520');
}).fadeTo('fast', 1);
});
}
Upvotes: 1
Reputation: 2107
Because you are in a loop, need a variable scope to keep reference to i
in the handler.
function testIndex(navIndex){
$.each(Array(5), function(i) {
if(i != navIndex){
$('#nav a:eq('+i+')').hover(function(){
$(this).fadeTo('fast', 0.3, function(){
$(this).css('background-color','#ff3520');
$('#nav li:eq('+i+')').css('color', '#ffffff');
}).fadeTo('fast', 1);
},
function(){
$(this).fadeTo('fast', 0.3, function(){
$(this).css('background-color', '#e8e8e8');
$('#nav li:eq('+i+')').css('color', '#ff3520');
}).fadeTo('fast', 1);
});
}
});
}
In JavaScript calling a function makes a variable scope, so I used $.each
for the loop, because it calls the function for each array index.
Upvotes: 5