jQuery或JavaScript检查图像是否加载完成

34

我知道在Stackoverflow上有很多这样的问题,但我没有找到一个适用于最近版本的jQuery(1.10.2)的解决方案。

我尝试过:

$(".lazy").load(function (){}

但是经过一些研究,我相信在jQuery 1.8中使用.load来检测图像加载已经过时了。我需要做的是,在图片加载完成后触发一个图像调整大小的函数。我无法控制HTML,并且现在我不得不通过附加属性(通过.attr())在页面加载时使用jQuery添加图像尺寸,以便我可以使用懒加载js。

问题是我需要一种准确的方式来延迟所有各种脚本,直到图像正确加载,否则有时函数会在每个图像都加载之前触发。我尝试使用$(window).load(function (){});,但有时它仍然在每个图像都加载之前触发。


你确定使用 $(window).load() 吗?我从未遇到过这个问题,而且根据 jQuery 文档所述:“在页面完全加载(包括图形)后运行函数。” - Mister Epic
你可以使用$(document).ready()来检查DOM是否已经准备好。 - patel.milanb
我会重新运行我的测试并仔细检查我是否正确关于window.load。 - Gerico
但我相信经过一些研究,这在jQuery 1.8中已被弃用。什么被弃用了? - A. Wolff
更新问题。我的意思是,我认为自1.8版本以来,使用.load来检测图像加载已经不起作用了。 - Gerico
显示剩余2条评论
5个回答

52

我通常会这样做:

var image = new Image();
image.onload = function () {
   console.info("Image loaded !");
   //do something...
}
image.onerror = function () {
   console.error("Cannot load image");
   //do something else...
}
image.src = "/images/blah/foo.jpg";

记住,加载是异步的,因此您必须在onloadonerror事件内继续脚本。


如果我正在加载大量图像列表,我需要引用所有图像路径吗? - Gerico
嗯,这取决于你的想法。如果该过程需要在开始之前加载所有图像,则是的,您必须全部加载它们。 - Darko Romanov
如果我的列表是动态的,我可以创建一个变量来查看所有进来的图像的src属性,然后以这种方式应用它吗? - Gerico
是的,当然可以。静态数组只是一个例子,您可以在开始执行preload函数之前先读取所有源代码。 - Darko Romanov

30

如果您在将任何事件监听器附加到图像之前已经设置了<img>.src,则图像对象还有一个有用的.complete属性,您可以使用它:

var img=document.getElementById('myimg');
var func=function(){
    // do your code here
    // `this` refers to the img object
};
if(img.complete){ 
    func.call(img);
}
else{ 
    img.onload=func; 
}

参考:http://www.w3schools.com/jsref/prop_img_complete.asp


这正是我需要的,用于捕获通过 $(xx).html() 调用加载的图像的末尾。 - Nick

20

我会给需要这个约束条件的图像赋予一个类名,例如mustLoad,其中:

<img class="mustLoad" src="..." alt="" />

然后创建一个通用的图像加载处理函数,例如:

$('img.mustLoad').on('load',function(){
        /* Fire your image resize code here */
});

编辑

针对您在上面提到废弃 .load() 的评论,.load() 已被废弃,并推荐使用 .on('load') 以减少onLoad 事件和 Ajax 加载之间的歧义。


14

在等待加载多张图片的情况下:

var images = $("#div-with-images img");
var unloaded = images.length;
images.on('load', function(){
  -- unloaded;
  if (!unloaded) {
    // here all images loaded, do your stuff
  }
});

3
我需要做的是在图像加载完成后启动图像大小调整函数。
您确定需要等待图像加载吗?在调整大小之前等待图像加载可能会导致页面布局大幅跳动,特别是对于文件较大(例如动画GIF)的图片。
通常情况下,对于图像调整大小,您只需要知道图像的固有尺寸。虽然没有事件可以告诉您这一点,但轮询图像以获取数据非常容易。以下代码可能特别有效:
<img src="..." data-resizeme="123" />

(function() {
    var images, l, i, tmp;
    if( document.querySelectorAll) {
        images = [].slice.call(document.querySelectorAll("img[data-resizeme]"),0);
    }
    else {
        tmp = document.getElementsByTagName("img");
        images = [];
        // browser compatibility is fun!
        for( i=tmp.length-1; i>=0; i--) {
            if( tmp[i].getAttribute("data-resizeme")) images.unshift(tmp[i]);
        }
    }

    for( i=images.length-1; i>=0; i--) {
        images[i].onload = resizeImage;
        images[i].onerror = cancelImageResize;
    }
    var timer = setInterval(function() {
        for( i=images.length-1; i>=0; i--) {
            if( images[i].width) {
                resizeImage.call(images[i]);
                images[i].onload = null;
                cancelImageResize.call(images[i]);
            }
        }
        if( images.length == 0) clearInterval(timer);
    },100); // adjust granularity as needed - lower number is more responsive.

    function cancelImageResize() {
        var i;
        for( i=images.length-1; i>=0; i--) {
            if( images[i] == this) {
                images.splice(i,1);
                break;
            }
        }
    }

    function resizeImage() {
        console.log("Image "+this.src+" is "+this.width+"x"+this.height);
    }
})();

希望这能帮到你!

"data-resizeme="123" - 具体来说,这个123是我想要调整大小的图像尺寸吗?" - Gerico
1
你可以做到。在 resizeImage 函数中,使用 parseInt(this.getAttribute("data-resizeme"),10) 来获取值,然后应用它。关键是要有一个属性存在。你可以自行决定如何使用它。 - Niet the Dark Absol
使用 setInterval 来创建轮询函数非常糟糕,这是管理异步函数的最差方法,应该使用回调系统代替。 - Darko Romanov
@DarkoRomanov 嗯...你会如何建议轮询一个没有关联事件处理程序的东西? - Niet the Dark Absol
事件是Image DOM对象的onload,您只需要一个包含每个图像URL的数组和指向当前图像的简单指针。当图像加载完成时,您再次调用相同的加载函数,增加指针。请参见Fiddle http://jsfiddle.net/93Q7Y/。 - Darko Romanov
显示剩余6条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接