TrueBlue TrueBlue - 2 days ago 5
jQuery Question

Obtaining a selector event index from within a dynamic element list

I wonder if someone can provide an insight into how I might solve a problem of obtaining an event index. I suspect that closures may be a part of the solution but would appreciate some insight.

First I build an HTML5 video container dynamically, for example this builds with an ajax routine that calls a php script that loops through and builds this depending on how many videos I want in the popup modal:

<div id="ids_<?php echo $i+1;?>" >
<h5><?php echo $route_title;?></h5>
<video id ="myPlayer_<?php echo $i+1;?>"
width="100%" poster="videos/posters/<?php echo $poster_name;?>"
controls data-info ='<?php echo $jsonData;?>' >
<source src="videos/<?php echo $video_name;?>" type="video/mp4">
Your browser does not support HTML5 video.
</video>
<p><?php echo $route_description;?></p>
</div>


You can see that the key element is the video
id=myPlayer_1, myPlayer_2 etc
.
I now create the modal box with all the video elements within it, using the following code snippet. ( The
'data_val[0]'
holds the php generated code shown above).

$(".modal-boxes").append('<div id="dialog_1" title="Most popular videos">'+data_val[0]+'</div>');
var numItems = $('.modal-boxes').length;
var hsize = numItems*320;
if (hsize > 600) hsize = 600;
$("#dialog_1").dialog({ width: 250, height: hsize, dialogClass: 'no- close video-dialog'});
var popUpPlayer =[];
for (var i= 1; i <= numItems; i++ ){
popUpPlayer[i] = document.getElementById("myPlayer_"+ i);
}


In the HTML modal-boxes is declared as:

<div class="modal-boxes"> </div>


And I can now use the these objects in the following way. The code inside is common but does not need to be. For example:

popUpPlayer[index].onplay = function() {
'do something in here once the user clicks the play button'
}


Now the question I have is how does javascript know which index to apply when the user clicks on say third video, which might be index = 3?

I hope this makes sense.

Thanks

Answer

here you have a demo, so you can see that each function knows which index got on its own

notice the first example preserves the expected index, while the counter-examples gets the last value of i1 which was 7

var numItems = 6;
var popUpPlayer = [];

//// callbacks know what was their index at the time the closure took place ////

for (var i3 = 1; i3 <= numItems; i3++) {
  popUpPlayer[i3] = {}; // dummy object to mimic
  popUpPlayer[i3].onplay = myNewCallback(i3);
}

function myNewCallback(index) {
  return function() {
    console.log('callback says: ' + index);
  };
}

for (var i4 = 1; i4 <= numItems; i4++) {
  popUpPlayer[i4].onplay();
}

//// counter-example below, will always print 7 ////

for (var i1 = 1; i1 <= numItems; i1++) {
  popUpPlayer[i1] = {}; // dummy object to mimic
  popUpPlayer[i1].onplay = function() {
    console.log('onplay says: ' + i1);
  };
}

for (var i2 = 1; i2 <= numItems; i2++) {
  popUpPlayer[i2].onplay();
}

Comments