要求jQuery在执行某些操作之前等待所有图像加载的正式方式

在jQuery中,当你这样做:

$(function() {
alert("DOM is loaded, but images not necessarily all loaded");
});

它等待DOM加载并执行您的代码。如果没有加载所有的图像,那么它仍然执行代码。这显然是我们在初始化任何DOM内容(如显示或隐藏元素或附加事件)时所需要的。

假设我想要一些动画我不想让它运行直到所有图像都加载完毕。jQuery中有官方的方法来做到这一点吗?

我拥有的最好的方法是使用<body onload="finished()">,但我真的不想这样做,除非我必须这样做。

注意:在ie浏览器中有一个jQuery 1.3.1中的bug,它实际上是在执行$function() { }中的代码之前等待所有图像加载。所以如果你正在使用这个平台,你会得到我正在寻找的行为,而不是上面描述的正确行为。

377144 次浏览

使用jQuery,当加载DOM时使用$(document).ready()来执行一些东西,当所有其他东西也加载时使用$(window).on("load", handler)来执行一些东西,比如图像。

如果你有很多jollyrogerNN JPEG文件(或其他合适的文件),你可以在以下完整的HTML文件中看到差异:

<html>
    <head>
        <script src="jquery-1.7.1.js"></script>
        <script type="text/javascript">
            $(document).ready(function() {
                alert ("done");
            });
        </script>
    </head><body>
        Hello
        <img src="jollyroger00.jpg">
        <img src="jollyroger01.jpg">
        // : 100 copies of this in total
        <img src="jollyroger99.jpg">
    </body>
</html>

这样,在加载图像之前就会出现警告框,因为此时DOM已经准备好了。如果你改变:

$(document).ready(function() {

成:

$(window).on("load", function() {

然后警告框不会出现,直到图像加载。

因此,要等待整个页面准备就绪,您可以使用如下代码:

$(window).on("load", function() {
// weave your magic here.
});

$(window).load()只在页面第一次加载时起作用。如果你正在做动态的事情(例如:点击按钮,等待一些新的图像加载),这是行不通的。要实现这一点,你可以使用我的插件:

下载

/**
*  Plugin which is applied on a list of img objects and calls
*  the specified callback function, only when all of them are loaded (or errored).
*  @version: 1.0.0 (Feb/22/2010)
*/


(function($) {
$.fn.batchImageLoad = function(options) {
var images = $(this);
var originalTotalImagesCount = images.size();
var totalImagesCount = originalTotalImagesCount;
var elementsLoaded = 0;


// Init
$.fn.batchImageLoad.defaults = {
loadingCompleteCallback: null,
imageLoadedCallback: null
}
var opts = $.extend({}, $.fn.batchImageLoad.defaults, options);
        

// Start
images.each(function() {
// The image has already been loaded (cached)
if ($(this)[0].complete) {
totalImagesCount--;
if (opts.imageLoadedCallback) opts.imageLoadedCallback(elementsLoaded, originalTotalImagesCount);
// The image is loading, so attach the listener
} else {
$(this).load(function() {
elementsLoaded++;
                

if (opts.imageLoadedCallback) opts.imageLoadedCallback(elementsLoaded, originalTotalImagesCount);


// An image has been loaded
if (elementsLoaded >= totalImagesCount)
if (opts.loadingCompleteCallback) opts.loadingCompleteCallback();
});
$(this).error(function() {
elementsLoaded++;
                

if (opts.imageLoadedCallback) opts.imageLoadedCallback(elementsLoaded, originalTotalImagesCount);
                    

// The image has errored
if (elementsLoaded >= totalImagesCount)
if (opts.loadingCompleteCallback) opts.loadingCompleteCallback();
});
}
});


// There are no unloaded images
if (totalImagesCount <= 0)
if (opts.loadingCompleteCallback) opts.loadingCompleteCallback();
};
})(jQuery);

我写了一个插件,可以在图像加载到元素时触发回调,或者每加载一个图像就触发一次。

它类似于$(window).load(function() { .. }),除了它允许您定义任何选择器进行检查。如果你只想知道#content(例如)中的所有图像何时加载,这是为你准备的插件。

它还支持加载CSS中引用的图像,如background-imagelist-style-image等。

jQuery插件

  • # EYZ0。
  • # EYZ0。
  • # EYZ0。
  • # EYZ0。

示例使用

$('selector').waitForImages(function() {
alert('All images are loaded.');
});

# EYZ0。

更多的文档可以在GitHub页面上找到。

对于那些希望在$(window).load触发后收到请求的单个图像下载完成通知的人,可以使用image元素的load事件。

例如:

// create a dialog box with an embedded image
var $dialog = $("<div><img src='" + img_url + "' /></div>");


// get the image element (as a jQuery object)
var $imgElement = $dialog.find("img");


// wait for the image to load
$imgElement.load(function() {
alert("The image has loaded; width: " + $imgElement.width() + "px");
});

用jQuery我来这个…

$(function() {
var $img = $('img'),
totalImg = $img.length;


var waitImgDone = function() {
totalImg--;
if (!totalImg) alert("Images loaded!");
};


$('img').each(function() {
$(this)
.load(waitImgDone)
.error(waitImgDone);
});
});

演示:http://jsfiddle.net/molokoloco/NWjDb/

使用imagesLoaded PACKAGED v3.1.8(最小化时6.8 Kb)。这是一个相对较老的项目(自2010年以来),但仍然是活跃的项目。

你可以在github上找到它: # EYZ0 < / p >

他们的官网: # EYZ0 < / p >

为什么它比使用更好:

$(window).load()

因为你可能想要动态加载图像,就像这样:jsfiddle

$('#button').click(function(){
$('#image').attr('src', '...');
});

我建议使用imagesLoaded.js javascript库。

为什么不使用jQuery的$(window).load()?

正如在https://stackoverflow.com/questions/26927575/why-use-imagesloaded-javascript-library-versus-jquerys-window-load/26929951上的回答

这是一个范围问题。imagesLoaded允许你瞄准一组图像,而$(window).load()瞄准所有资产 -包括所有图像,对象,.js和.css文件,甚至iframe。imagesLoaded很可能比$(window).load()更早触发,因为它针对的是一组较小的资产。

其他使用图像加载的好理由

资源

这样,当body或任何其他容器(取决于您的选择)内的所有图像都加载时,您可以执行一个操作。纯JQUERY,不需要插件。

var counter = 0;
var size = $('img').length;


$("img").load(function() { // many or just one image(w) inside body or any other container
counter += 1;
counter === size && $('body').css('background-color', '#fffaaa'); // any action
}).each(function() {
this.complete && $(this).load();
});

我的解决方案类似于molokoloco。jQuery函数:

$.fn.waitForImages = function (callback) {
var $img = $('img', this),
totalImg = $img.length;


var waitImgLoad = function () {
totalImg--;
if (!totalImg) {
callback();
}
};


$img.each(function () {
if (this.complete) {
waitImgLoad();
}
})


$img.load(waitImgLoad)
.error(waitImgLoad);
};

例子:

<div>
<img src="img1.png"/>
<img src="img2.png"/>
</div>
<script>
$('div').waitForImages(function () {
console.log('img loaded');
});
</script>

到目前为止,没有一个答案给出了似乎是最简单的解决方案。

$('#image_id').load(
function () {
//code here
});

我已经找到了这个解决方案:@Luca Matteis : # EYZ0 < / p >

但是我稍微编辑了一下,如下图所示:

function showImage(el){
$(el).removeClass('hidden');
$(el).addClass('show');


$(el).prev().removeClass('show');
$(el).prev().addClass('hidden');
}


<img src="temp_image.png" />
<img class="hidden" src="blah.png" onload="showImage(this);"/>