预加载图像后触发事件

这是我用来预装图像的代码,我不确定它是否是最好的。 我的问题是,如何触发和事件,例如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]; } 

如果您愿意,可以使用新的“$ .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对象漂浮在周围可能有点风险,但如果是这样,可以通过移动闭包来轻松修复。 编辑其实我会自己改变它因为它让我烦恼:-)

由于你的标签包含jQuery,这就是我在jQuery中所做的,从这个相关的答案中得到了很多灵感:

 function preloadImages(images, callback) { var count = images.length; if(count === 0) { callback(); } var loaded = 0; $.each(images, function(index, image) { $('').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的内置原型来使用相关的答案。

我已经看到用于纠正Masonry nice jQuery插件(用于在页面上制作漂亮的布局组合的插件)上的行为的东西。 这个插件存在包含图像的块的问题,并且应该在加载图像时延迟其工作。

第一种解决方案是延迟onLoad事件而不是document.ready。 但是这个事件可能要等很长时间。 所以他们使用jquery.imagesloaded.js来检测div中的所有图像都被加载了; 特别是这个非常简短的代码可以处理缓存的图像,有时不会触发加载事件。

查看: http : //engineeredweb.com/blog/09/12/preloading-images-jquery-and-javascript 。 它使用jQuery。 在评论中,您的直接问题由某人解决,并在那里发布了解决方案。 我认为它符合您的需求。

作为替代方案,您可以使用CSS技术预加载图像,如下所示:

http://perishablepress.com/press/2008/06/14/a-way-to-preload-images-without-javascript-that-is-so-much-better/

然后使用全局onLoad事件,该事件在加载所有内容时触发

//这是一个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; } 

我正在寻找能够在一整天内完成这项工作的技术,我终于找到了解决我所有问题的方法: https : //github.com/htmlhero/jQuery.preload

它甚至可以按任意大小(例如,每次两个)的顺序为您顺序预加载,并在每次批处理完成时触发回调。

jquery串行预加载多个图像可以通过回调完成。

 function preload_images(images_arr, f, id){ id = typeof id !== 'undefined' ? id : 0; if (id == images_arr.length) return; $('').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 }); 

基于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); }); }; 

今天我需要预先加载图像并在加载所有图像后执行一些代码,但是没有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): Promise> { return new Promise((resolve, reject) => { ... function _loadImage(src: string, arr: Array) { ... } ... } 

你可以像这样使用。 有问题的url返回’null’。

 loadImages(['http://sofzh.miximages.com/javascript/nodejs-512.png', 'http://foo_url']) .then(function(arr) { console.log('[???]', arr); })