tags:

views:

2496

answers:

5

I trying to wait for images finished to load but it seems that the load event is never matched.

Here's my code :

$(function() {
var arrowWidth = 22;
var currentImageID = -1;
var imageOffsets = new Array();
var loadedImages = 0;
var numberOfImages = $("div#sliderGallery > ul > li").size();

$("div#sliderGallery > ul").hide();
$("div#sliderGallery").append("<div id=\"loading\"></div>");
$("div#sliderGallery > div#loading").append("Chargement en cours ...<br>");
$("div#sliderGallery > div#loading").append("<img src=\"progressbar.gif\" />");

function setOffset(imageID) {
 if (imageID != currentImageID) {
  $("ul#slide_items > li > img#"+currentImageID).fadeTo(0, 0.2); 
  currentImageID = imageID;
  $("ul#slide_items > li > img#"+currentImageID).fadeTo("slow", 1);
  $("div#sliderGallery > ul").css("left", imageOffsets[imageID][0]+"px");
  $("div#slideGallery > span.arrow").css("width", imageOffsets[imageID][1]+"px"); 
  $("div#sliderGallery > span#left").css("left", imageOffsets[imageID][2]+"px");
  $("div#sliderGallery > span#right").css("left", imageOffsets[imageID][3]+"px");
 }
}


$("div#sliderGallery > ul > li > img").load(function() {
 alert("never executed ...");

 loadedImages++;
 if (loadedImages == numberOfImages) {
  $("div#sliderGallery > div#loading").remove();
  $("div#sliderGallery").css("overflow", "hidden");
  $("div#sliderGallery > ul").show();
  $("div#sliderGallery").append("<span id=\"left\" class=\"arrow\"><img src=\"arrow_left.png\" /></span>");
  $("div#sliderGallery").append("<span id=\"right\" class=\"arrow\"><img src=\"arrow_right.png\" /></span>");
  $("div#slideGallery > span.arrow").fadeTo(0, 0.5);
  $("div#slideGallery > span.arrow").css("padding-top", Math.round((600-146)/2)+"px"); 

  var ulWidth = $("div#sliderGallery").innerWidth();

  var imageID = 0;
  var imageWidthSum = 0;
  $("div#sliderGallery > ul > li > img").each(function() {
   image = jQuery(this);
   image.attr("id", imageID);
   image.fadeTo(0, 0.2);

   imageOffsets[imageID] = new Array();
   // Offset applied to images 
   imageOffsets[imageID][0] = Math.round(ulWidth/2-(imageWidthSum+image.innerWidth()/2));
   // Width applied to span
   imageOffsets[imageID][1] = Math.round(image.innerWidth()/2+arrowWidth);
   // Offset apply to the left span
   imageOffsets[imageID][2] = Math.round($("div#sliderGallery").offset().left+ulWidth/2-imageOffsets[imageID][1]);
   // Offset apply to the right span
   imageOffsets[imageID][3] = imageOffsets[imageID][1]+imageOffsets[imageID][2];

   imageID++;
   imageWidthSum += image.innerWidth();
  });

  setOffset(0);
 }
});

});

And html code : link text

Why this line "alert("never executed ...");" isn't executed ?

Thanks in advance, i'm going insane with this problem :)

A: 

This may not be the answer to your problem, but I notice you reference div#slideGallery and div#sliderGallery. Are these two seperate divs or is that a typo?

I receive the alert box with IE 8

Jack
I went to the website and that portion did execute on my side. Your selecting two seperate divs:$("div#sliderGallery").append("<span id=\"left\" class=\"arrow\"><img src=\"arrow_left.png\" /></span>"); $("div#sliderGallery").append("<span id=\"right\" class=\"arrow\"><img src=\"arrow_right.png\" /></span>"); $("div#slideGallery > span.arrow").fadeTo(0, 0.5); $("div#slideGallery > span.arrow").css("padding-top", Math.round((600-146)/2)+"px");slideGallery and sliderGallery
Jack
It was a typo error, fix nowBut it changed nothing.alert code is executed the first time the page is open, but next visits, code doesn't executed ...Once images are cached, load event doesn't work anymore ...
Fabien Engels
A: 

From the docs:

Note: load will work only if you set it before the element has completely loaded, if you set it after that nothing will happen. This doesn't happen in $(document).ready(), which jQuery handles it to work as expected, also when setting it after the DOM has loaded.

Can you put it in a $(document).ready()?

RedWolves
I change the first line to : $(document).ready(function() {Still don't work :(
Fabien Engels
A: 

You need to check if all images are already loaded (happens on fast connections or if loaded from cache) by comparing numberOfImages to $("div#sliderGallery > ul > li > img").length just after you registered the onload handler. Most browsers only fire the event if the images have finished loading after the handler is registered, some fire it even if it has already finished loading before but I wouldn't rely on that. Since you usually do such initializations on $(document).ready() you trap into that problem even more often because they probably have a good amount of images loaded before.

For concurrency reasons you may also add some boolean flag to be toggled and checked when you fire the block (better make it a function) to get executed if preloading has finished or you may end up executing that block multiple times.

Also make sure you don't use your internal loadedImages counter since it may never count to the full value for the above reasons. Better check $("div#sliderGallery > ul > li > img").length each time.

I don't know if it's relevant but when I coded a preloader I registered with jQuery's $().each function using .onload directly for each image. Maybe there was some problem back then or I just didn't know $().load. You may want to try if it makes any difference.

Energiequant
+2  A: 

With IE the event onload on images seems to be problematic. In addition of attach onload event handler, for each image you can try to check if attribute complete is equal to true.

$("div#sliderGallery > ul > li > img").each( function() { 
    if ($(this)[0].complete) {
        // track image is loaded
    }
});

This may works also for cached images.

tanathos
A: 

I see, thanks for your explanations to all :)

So what is the best pratices to check if all images are loaded ? A loop with this code inside it executed until all images are loaded ? It sound like an ugly way to do it :) (edit: it's ok i'm a noob, i find a better way without using a stupid loop :) )

Fabien Engels