OdieO
OdieO

Reputation: 7004

Add listener to dynamically created element - `on` not working

I'm creating a list of thumbnails and trying to add click listeners to each of them:

 function loadVideoList(chan) {
    var this_chan = chan, $list = $('<div></div>');

    console.log("Globals.videos[this_chan].video.length = " + Globals.videos[this_chan].video.length);

    for(var i in Globals.videos[this_chan].video) {
        var this_video = Globals.videos[this_chan].video[i];


        var $thumbnail = $('<img id="video-list-thumb-' + i + '"' + ' rel="' + i + '"' +
                           ' title="' + this_video.title_quot + '"/>');


        $thumbnail
            .attr('src', 'img/noimage.png')
            .attr('style', 'display:block;')
            .attr('data-original', getThumbnailUrl(this_chan, i));


        ////////////////////////////////////
        // Hangout 
        $('#video-list-thumb-' + i).on("click", function() {
            console.log("click --  i = " + i);

            addButtonBinding('#video-list-thumb-' + i);
        });

        $list.append($thumbnail);
    }

    $('#video-list')
        .stop(true, true)
        .html($list)
        .show()
        .animate({ width:140, padding: 0 }, 1000, function() {
            $('img').lazyload({
                effect : "fadeIn",
                container: $("#video-list")
            });
        });
}

Doesn't work. Nothing happens. console.log("click -- i = " + i); never gets logged. I'm using JQuery 2.1.0.

If I add the following loop to the end of the function, trying to bind the listeners after they elements are inserted into the DOM:

 for(var i in Globals.videos[this_chan].video) {
    $('#video-list-thumb-' + i).on("click", function() {
        console.log("click --  i = " + i);

        addButtonBinding('#video-list-thumb-' + i);
    });
 }

Then the value that's logged for i is always the last value of i - the length of the array - 1. And this is passed to my addButtonBinding function. So whichever thumbs I click it's not loading the corresponding video, it loads the last video in the array.

Upvotes: 0

Views: 60

Answers (1)

Rajaprabhu Aravindasamy
Rajaprabhu Aravindasamy

Reputation: 67217

Try,

$thumbnail.attr('src', 'img/noimage.png')
          .attr('style', 'display:block;')
          .attr('data-original', getThumbnailUrl(this_chan, i));
          .on("click", function() {
              //Your code here.
           });

This would work, but binding event inside a loop is not a good practice. You should rather add a common class to those image elements say imgClass and bind events to it by using event delegation, out side the loop.

$('#video-list').on('click','.imgClass',function(){
  //code goes here.
});

Upvotes: 2

Related Questions