I'm trying to add a load event on my images with native javascript. Here is the code :
var imgs = $("figure img"); // querySelectorAll
for(var i = 0, l = imgs.length ; i < l ; ++i)
imgs[i].addEventListener("load", img_loaded, false);
But my function img_loaded is never called. imgs.length is 3, and I'm sure the event is attached.
Any idea ? I have the same problem with window, window.addEventListener("load", window_loaded, false) sometimes works.
I'm using requirejs and it is a nodejs server. Testing on both Chrome and Firefox.
(Note: The $ isn't related to jQuery, it's just an alias for document.querySelectorAll.)
The most likely reason is that the load event has already fired. With an img, you can check whether its load event has been fired by checking its complete property.
This will reliably call img_loaded for the related images, for instance:
var imgs = $("figure img");
var img;
for(var i = 0, l = imgs.length ; i < l ; ++i) {
img = imgs[i];
img.addEventListener("load", img_loaded, false);
if (img.complete) {
img_loaded.call(img);
img.removeEventListener("load", img_loaded, false);
}
}
You may be wondering why, in the above, first I attach the event handler, then I check whether img.complete is checked, and if so I remove the event handler and call it. That's to prevent missed called. There's only one main JavaScript thread, but the browser is not single-threaded. If we checked complete first, then added the handler on the next line, it would be perfectly valid for the browser, between those two lines, to see that it has finished loading the image, look for handlers for the load event, not see any, and set complete — and we wouldn't get a callback at all. It's really unlikely, but it can happen.
For the same reason, the above may call img_loaded twice in very rare situations for the same image. So you want to handle the possibility it's already been called, in the function.