2

I am trying to write a system that will generate and populate a form with some text stored in several objects in an array.

I loop through the array, and then through the number of rows in the description to add some breaks so that two other columns line up with the first row of each group.

All the text is in one of 3 divs that are positioned above a bunch of other divs with borders. These draw lines to visualize the form boxes.

Each time one of these background divs is created I give it a class "i" from the for loop. Thus grouping them all to the current object. This way when I hover over any one of the boxes it highlights them all as one group.

My problem is that when I hover over any div it says "i" is equal to 6. (I have 6 items total 0-5 in the array). It should echo 0-5 depending on what "i" was in the loop at the time they were bound.

If I move my .hover() call into a separate function (outside of the for loop) and then call that function in the same place like setHover(i); it works.....

This is probably something really obvious but I'm really confused by this behavior. Any help would be much appreciated.

for(i=0; i<g_workEntries.length; i++)
    {
        curEntry = g_workEntries[i];  //current object
        rowCount = curEntry.numRows;  // total number rows for this object

        //add the big block of description text
        $('#descriptionText').append('<div>'+curEntry.description+'</div><br/>');

         if(curEntry.price != null) 
         {  
            $('#priceText').append('$'+curEntry.price); //If there is a price add it
         }

        if(curEntry.workCode != null) 
        {
            $('#workCodesText').append(curEntry.workCode);//If there is a work id add it
        }

        for(x=0; x < rowCount; x++)
        {
            generateRow(''+i); //generate a background row (what the text sits on & gets highlited on hover).

            $('#priceText').append('<br/>');     //add a break for  the first lien & every subsequent line of the description.
            $('#workCodesText').append('<br/>'); 
        }


        console.log('added hover for: '+i); //<-- this works and says 0-5

        //////////THIS CAUSES THE ISSUE////////
        ///It always echos 6 whenever I hover
        ///It should be echoing 0-5 depending
        ///on what row group gets passed (i)

        $('.'+i).hover(
            function(){console.log(i+' ON');},
            function(){console.log(i+' OFF');}
        );
    }
2
  • 1
    Do note that classes and IDs in CSS should not begin with a numerical character - instead, it should begin with a dash, an underscore or any alphabetical character. See more here: stackoverflow.com/a/449000/395910 Commented Dec 28, 2013 at 12:09
  • 1
    Thanks for the advice Terry, I will change that. Good link Zaheer Commented Dec 28, 2013 at 12:15

1 Answer 1

3

This is what is called a closure.You should enclose it in another scope:

for(var i =0 i<n;i++)
{

  (function(index){

    $('.'+index).hover(function(){
        console.log(index);
    })
  })(i)
}

EDIT: As Bill Criswell pointed out, since you're using jQuery you can enclose the scope using $.each function to iterate through an array instead of using for statement:

$.each( g_workEntires, function( index, curEntry ){ ... });

The thing that happens is that the loop is finished long time before the hover function callback is called. In javascript variables have function scope, not block scope. So the var i, has the value = 6 when the loop finishes, and after some time the hover callback is called and finds the i variable with the value of 6.

Sign up to request clarification or add additional context in comments.

6 Comments

this "strange" scope error arrives at SO every two days, please explain that?
no sarcasm sorry - i see people ask about closure (unknowingly) when they first encounter anonymous functions :)
You're using jQuery, you could use $.each() instead of a for loop which would allow you to go through like you expect since it creates the closure for you.
that's right about $.each , i just explained why it did not work :)
$.each( g_workEntires, function( index, curEntry ){ ... }); would do the trick!
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.