wpakt
wpakt

Reputation: 1083

Bind on mouseover or hover to dynamically generated elements

I need to bind a hover for items generated in the javascript. For example when I mouseover an icon element, a unique text would appear about that icon:

for (var i = 0; i < items.length; i++) {
    $('.items').append('<div class="icon' + i + '"></div>');
    $('.itemInfo').append('<div class="info' + i + '">' + name + '</div>');
}

I have tried using jQuery .hover() and .on(), and inject the info through javascript when the icon is hovered over, but it would always grab the info of index. I also tried (example below) setting the info and using .hide(), then .show() when the icon is hovered over and nothing appears at all. However, the debugger tells me that it is going into the function and the index is still the last one.

for (var i = 0; i < items.length; i++) {
    $('.items').append('<div class="icon' + i + '"></div>');
    $('.itemInfo').append('<div class="info' + i + '">' + name + '</div>');

    $('.icon' + i).on({
        mouseenter: function () { $('.itemInfo' + i).show(); },
        mouseleave: function () { $('.itemInfo' + i).hide(); }
    });
}

Note that I have the icons and info separated into two different divs, for UI styling purposes. There are other icons being generated, where the number of items are known, so they are able to follow that structure. Not sure if breaking away from the way the html/css is set up and putting both icon and info under the same div would be better in handling this situation where I don't know how many items are being generated.

Upvotes: 0

Views: 3125

Answers (1)

AWolf
AWolf

Reputation: 8970

As mentioned in the comment from Jeromy French you have to use event delegation.

If I've understood it correctly this jsFiddle should work for you.

var items = ['first', 'second', 'third'];

for (var i = 0; i < items.length; i++) {
    $('.items').append('<div class="icon' + i + '">Item ' + (i + 1) + '</div>');
    $('.itemInfo').append('<div class="info' + i + '">' + items[i] + '</div>');
}

$('.items').on('mouseover', "div[class^='icon']", function(evt){
    //console.log('over', evt);
    var id = evt.currentTarget.className.split('icon')[1];
    //console.log(id);
    $('.info' + id).show();
});

$('.items').on('mouseout', "div[class^='icon']", function(evt){
    //console.log('out', evt);
    var id = evt.currentTarget.className.split('icon')[1];
    //console.log(id);
    $('.info' + id).hide();
});
div[class^="info"] {
    display: none;
}

.itemInfo {
    background-color: lightgray;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="items"></div>
<div class="itemInfo"></div>

Upvotes: 4

Related Questions