预加载图像后触发事件

时间:2011-04-11 15:29:13

标签: javascript jquery

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

10 个答案:

答案 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技术预加载图像,如下所示:

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

然后使用全局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); 
})