Question

I've dynamically loaded lots of pairs of elements onto my page. Each pair has a descriptor in a list, and a highlighter overlaid on an image.

What I want is when a user hovers over the list item, that the other element is highlighted.

My current code below only ever highlights the last element in the .viewer, no matter which list item I hover over.

What's the best approach for handling this?

for (i = 0; i < Ajax.length; ++i) {
    var listid = 'listitem-'+i;
    var mapid = 'mapitem-'+i;

    $('.list').append('<div id="'+listid+'">Lots of Text</div>');
    $('.viewer').append('<div id="'+mapid+'">Here It Is</div>');

    $('#'+listid).hover(function(){
        $('#'+mapid).toggleClass('highlight');
    });
}
Was it helpful?

Solution

mapid has the last value assigned to it by the time the hover event handler is fired, so you need to make sure you have the relevant value.

Try putting the hover assignment inside an enclosure...

for (i = 0; i < Ajax.length; ++i) {
    var listid = 'listitem-'+i;
    var mapid = 'mapitem-'+i;

    $('.list').append('<div id="'+listid+'">Lots of Text</div>');
    $('.viewer').append('<div id="'+mapid+'">Here It Is</div>');

    (function(listid, mapid) {
        $('#'+listid).hover(function(){
            $('#'+mapid).toggleClass('highlight');
        });
    })(listid, mapid);
}

An alternative method would be to store the associated map ID with the list item, like this...

for (i = 0; i < Ajax.length; ++i) {
    var listid = 'listitem-'+i;
    var mapid = 'mapitem-'+i;

    $('.list').append('<div id="'+listid+'">Lots of Text</div>');
    $('.viewer').append('<div id="'+mapid+'">Here It Is</div>');

    $('#'+listid).data("associated-map-id", mapid);

    $('#'+listid).hover(function(){
        $('#'+$(this).data("associated-map-id")).toggleClass('highlight');
    });
}

Either will work and they'll give the same end result. Just choose what you prefer :)

OTHER TIPS

Move the hover handler into a closure, passing listid and mapid as arguments. This creates the variables in a new scope where they don't get affected by the mapid and listid that get overwritten in the higher scope.

for (i = 0; i < Ajax.length; ++i) {
    var listid = 'listitem-'+i;
    var mapid = 'mapitem-'+i;

    $('.list').append('<div id="'+listid+'">Lots of Text</div>');
    $('.viewer').append('<div id="'+mapid+'">Here It Is</div>');

    (function(listid, mapid){
        $('#'+listid).hover(function(){
            $('#'+mapid).toggleClass('highlight');
        });
    })(listid, mapid);
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top