这是我用来预加载图片的代码,我不确定它是否是最好的。 我的问题是,如何触发和事件,例如alert();对话框已经完成加载所有图像?
var preload = ["a.gif", "b.gif", "c.gif"];
var images = [];
for (i = 0; i < preload.length; i++) {
images[i] = new Image();
images[i].src = preload[i];
}
答案 0 :(得分:31)
如果您愿意,可以使用新的“$ .Deferred”:
var preload = ["a.gif", "b.gif", "c.gif"];
var promises = [];
for (var i = 0; i < preload.length; i++) {
(function(url, promise) {
var img = new Image();
img.onload = function() {
promise.resolve();
};
img.src = url;
})(preload[i], promises[i] = $.Deferred());
}
$.when.apply($, promises).done(function() {
alert("All images ready sir!");
});
让Image对象漂浮在周围可能有点风险,但如果是这样,可以通过移动闭包来轻松修复。 编辑其实我会自己改变它,因为它让我烦恼: - )
答案 1 :(得分:13)
由于你的标签包含jQuery,这就是我在jQuery中所做的,来自this related answer的重点灵感:
function preloadImages(images, callback) {
var count = images.length;
if(count === 0) {
callback();
}
var loaded = 0;
$.each(images, function(index, image) {
$('<img>').attr('src', image).on('load', function() { // the first argument could also be 'load error abort' if you wanted to *always* execute the callback
loaded++;
if (loaded === count) {
callback();
}
});
});
};
// use whatever callback you really want as the argument
preloadImages(["a.gif", "b.gif", "c.gif"], function() {
alert("DONE");
});
这依赖于对jQuery的加载函数的回调。
我不会仅仅因为我不喜欢使用Javascript的内置原型来使用相关的答案。
答案 2 :(得分:1)
我已经看到用于纠正Masonry漂亮的jQuery插件(用于在页面上制作漂亮的布局组合的插件)上的行为的东西。这个插件存在包含图像的块的问题,并且应该在加载图像时延迟他的工作。
首先解决方案是延迟onLoad事件而不是document.ready。但是这个事件可能要等很长时间。所以他们使用jquery.imagesloaded.js来检测div中的所有图像都被加载了;特别是这个非常简短的代码可以处理缓存的图像,有时不会触发加载事件。
答案 3 :(得分:0)
结帐:http://engineeredweb.com/blog/09/12/preloading-images-jquery-and-javascript。它使用jQuery。在评论中,您的直接问题由某人解决,并在那里发布了解决方案。我认为它符合您的需求。
答案 4 :(得分:0)
作为替代方案,您可以使用CSS技术预加载图像,如下所示:
然后使用全局onLoad事件,该事件在加载所有内容时触发
答案 5 :(得分:0)
//这是一个pre-jquery方法,但是jquery必然会更容易编写。
function loadAlbum(A, cb, err, limit){
// A is an array of image urls;
//cb is a callback function (optional);
//err is an error handler (optional);
// limit is an (optional) integer time limit in milliseconds
if(limit) limit= new Date().getTime()+limit;
var album= [], L= A.length, tem, url;
while(A.length){
tem= new Image;
url= A.shift();
tem.onload= function(){
album.push(this.src);
}
tem.onerror= function(){
if(typeof er== 'function') album.push(er(this.src));
else album.push('');
}
tem.src= url;
// attend to images in cache (may not fire an onload in some browsers):
if(tem.complete && tem.width> 0){
album.push(tem.src);
tem.onload= '';
}
}
// check the length of the loaded array of images at intervals:
if(typeof cb== 'function'){
window.tryAlbum= setInterval(function(){
if(limit && limit-new Date().getTime()<0) L= album.length;
if(L== album.length){
clearInterval(tryAlbum);
tryAlbum= null;
return cb(album);
}
},
100);
}
return album;
}
答案 6 :(得分:0)
我正在寻找能够全天工作的技术,我终于找到了解决所有问题的方法:https://github.com/htmlhero/jQuery.preload
它甚至可以按任意大小(例如,每次两个)的顺序为您顺序预加载,并在每次批处理完成时触发回调。
答案 7 :(得分:0)
jquery串行预加载多个图像可以通过回调来完成。
function preload_images(images_arr, f, id){
id = typeof id !== 'undefined' ? id : 0;
if (id == images_arr.length)
return;
$('<img>').attr('src', images_arr[id]).load(function(){
console.log(id);
f(images_arr[id], id);
preload_images(images_arr, f, id+1);
});
}
例如:
preload_images(["img1.jpg", "img2.jpg"], function(img_url, i){
// i is the index of the img in the original array
// can make some img.src = img_url
});
答案 8 :(得分:0)
根据上述Ben Clayton的回答。
可能存在图像加载一起失败并且仍然必须能够进行回调的情况。
这是我修改后的答案。
一个人很容易发现很多图像加载成功,有多少图像最终出错。回调中的this
将具有该信息
preloadImages(_arrOfImages, function() {
var response = this;
var hasError = response.errored.length + response.aborted.length;
if (hasError > 0) {
console.log('failed ' + hasError);
} else {
console.log('all loaded');
}
});
// JSFIDDLE: https://jsfiddle.net/bababalcksheep/ds85yfww/2/
var preloadImages = function(preload, callBack) {
var promises = [];
var response = {
'loaded': [],
'errored': [],
'aborted': []
};
for (var i = 0; i < preload.length; i++) {
(function(url, promise) {
var img = new Image();
img.onload = function() {
response.loaded.push(this.src);
promise.resolve();
};
// Use the following callback methods to debug
// in case of an unexpected behavior.
img.onerror = function() {
response.errored.push(this.src);
promise.resolve();
};
img.onabort = function() {
response.aborted.push(this.src);
promise.resolve();
};
//
img.src = url;
})(preload[i], promises[i] = $.Deferred());
}
$.when.apply($, promises).done(function() {
callBack.call(response);
});
};
答案 9 :(得分:0)
今天我需要预先加载图片并在加载所有图片后执行一些代码 ,但不使用jQuery 并使用Ionic2 / Typescript2。这是我的解决方案:
// Pure Javascript Version
function loadImages(arrImagesSrc) {
return new Promise(function (resolve, reject) {
var arrImages = [];
function _loadImage(src, arr) {
var img = new Image();
img.onload = function () { arr.push([src, img]); };
img.onerror = function () { arr.push([src, null]); };
img.src = src;
}
arrImagesSrc.forEach(function (src) {
_loadImage(src, arrImages);
});
var interval_id = setInterval(function () {
if (arrImages.length == arrImagesSrc.length) {
clearInterval(interval_id);
resolve(arrImages);
}
}, 100);
});
}
// Ionic2 version
private loadImages(arrImagesSrc: Array<string>): Promise<Array<any>> {
return new Promise((resolve, reject) => {
...
function _loadImage(src: string, arr: Array<any>) {
...
}
...
}
你可以这样使用。有问题的网址返回'null'。
loadImages(['https://cdn2.iconfinder.com/data/icons/nodejs-1/512/nodejs-512.png', 'http://foo_url'])
.then(function(arr) {
console.log('[???]', arr);
})