Dominic Sore
Dominic Sore

Reputation: 385

Variable can't been seen

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

Answers (2)

Felix Kling
Felix Kling

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

gray state is coming
gray state is coming

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

Related Questions