14

I have this piece of code that loops through an array and load images and notify when the images is loaded.

for (var i = 0; i < arr.length; i++) {                
    var imageObj = new Image();
    imageObj.src = url[i];
    imageObj.onload= (function(i){
                return function(){
                    console.log(i, 'loaded');
                }
            })(i);

}

It works fine. However if I try to do this it won't work:

imageObj.addEventListener('onload', function(
    console.log(i, 'loaded');
}, false);

What is the problem? And is there any way for me to avoid using closure in this case?

Brian Tompsett - 汤莱恩
  • 5,753
  • 72
  • 57
  • 129
Ethan
  • 1,488
  • 3
  • 19
  • 24
  • Not the only problem, but your second broken example is clearly broken JS, missing `i) {` at the end of the first line. – Lambart Oct 10 '14 at 22:57
  • Just to be on the safe side, shouldn't you first assign the event and then assign the src? – bashan May 04 '15 at 11:28

1 Answers1

23

One part of the problem: The event is not called onload, but load.

imageObj.addEventListener('load', function() { /* ... */ }, false);

Other than that, since i changes outside of the event listener function, you need a closure.

Anders Marzi Tornblad
  • 18,896
  • 9
  • 51
  • 66
  • 1
    @gillesc A normal ES5 array.forEach() will give you a new scope, so your bindings aren't always set on the last item. It will be less code than iterating through the indexes and adding your own closure too. – mikemaccana Sep 30 '14 at 11:05