Waiting for images loading with JQuery

流过昼夜 提交于 2019-11-28 02:01:17

问题


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 :)


回答1:


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.




回答2:


I wrote a plugin that fires callbacks when descendent images have finished downloading. Sort of a localised window.onload.

It's called waitForImages and usage is...

$('selector').waitForImages(function() {

    alert('All images are loaded.');

});

Readme.

It can also be configured to wait for images referenced in the CSS.




回答3:


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




回答4:


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()?




回答5:


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.



来源:https://stackoverflow.com/questions/1098788/waiting-for-images-loading-with-jquery

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!