预加载图像后触发事件

时间:2021-10-13 20:20:43

This is the code I use to preload images, I'm not sure if it's the best one. My question is, how can I fire and event, for an example alert(); dialog after is has finished loading all the images?

这是我用来预加载图像的代码,我不确定它是否是最好的。我的问题是,如何触发和事件,例如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 个解决方案

#1


31  

You can use the new "$.Deferred" if you like:

如果您愿意,可以使用新的“$ .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!");
});

Might be a little risky to leave the Image objects floating around, but if so that could be fixed easily by shifting the closure. edit in fact I'll change it myself because it's bugging me :-)

让Image对象漂浮在周围可能有点风险,但如果是这样,可以通过移动闭包来轻松修复。编辑其实我会自己改变它因为它让我烦恼:-)

#2


13  

Since your tags include jQuery, here's what I would do in jQuery, with heavy inspiration from this related answer:

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

function preloadImages(images, callback) {
    var count = images.length;
    if(count === 0) {
        callback();
    }
    var loaded = 0;
    $(images).each(function() {
        $('<img>').attr('src', this).load(function() {
            loaded++;
            if (loaded === count) {
                callback();
            }
        });
    });
};

// use whatever callback you really want as the argument
preloadImages(["a.gif", "b.gif", "c.gif"], function() {
    alert("DONE");
});

This relies on the callback to jQuery's load function.

这依赖于对jQuery的加载函数的回调。

I wouldn't use the related answer simply because I don't like mucking around with Javascript's built-in prototypes.

我不会仅仅因为我不喜欢使用Javascript的内置原型来使用相关的答案。

#3


1  

I've seen something used to correct behavior on Masonry nice jQuery plugin (a plugin used to make nice layout composition on pages). This plugin had problems with blocks containing images and should delay his work when the images are loaded.

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

First solution is to delay on the onLoad event instead of document.ready. But this event can be quite long to wait for. So they use jquery.imagesloaded.js which can detect that all images in a div are loaded; especially this very short and nice code can handle cached images which does not fire the load event sometimes.

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

#4


0  

Check out: http://engineeredweb.com/blog/09/12/preloading-images-jquery-and-javascript. It uses jQuery. In the comments, your direct issue is addressed by someone and a solution was posted there. I think it'll fit your needs.

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

#5


0  

As an alternative you could use a CSS technique to pre-load the images as shown here:

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

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

and then use the global onLoad event which is fired when everything has been loaded

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

#6


0  

//Here is a pre-jquery method, but jquery is bound to be simpler to write.

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

#7


0  

I'm searching for techniques that work for doing this all day now, and I finally found the solution to all my problems: https://github.com/htmlhero/jQuery.preload

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

It can even preload sequentially for you, in batches of any size (two at a time, for example), and fire a callback each time a batch completes.

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

#8


0  

jquery preloading multiple images serially can be done with a callback.

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

For example:

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

#9


0  

Based on answer from Ben Clayton above.

基于Ben Clayton的回答。

There can be case where images load fail all together and one must still be able to get callback.

可能存在图像加载一起失败并且仍然必须能够进行回调的情况。

Here is my revised answer. One ca easily find out hom many images loaded with success and how many ended up in error. this in callback will have that info

这是我修改后的答案。一个人很容易发现很多图像加载成功,有多少图像最终出错。回调中的这个将有这些信息

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/

// 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);
  });
};

#10


0  

Today I needed to preload images and execute some code only after all images are loaded, but without jQuery and using Ionic2/Typescript2. Here's my solution:

今天我需要预先加载图像并在加载所有图像后执行一些代码,但是没有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>) {
        ...
      }
      ...
 }

You can use like this. Problematic url returns 'null'.

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

loadImages(['https://cdn2.iconfinder.com/data/icons/nodejs-1/512/nodejs-512.png', 'http://foo_url'])
.then(function(arr) {
   console.log('[???]', arr); 
})

#1


31  

You can use the new "$.Deferred" if you like:

如果您愿意,可以使用新的“$ .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!");
});

Might be a little risky to leave the Image objects floating around, but if so that could be fixed easily by shifting the closure. edit in fact I'll change it myself because it's bugging me :-)

让Image对象漂浮在周围可能有点风险,但如果是这样,可以通过移动闭包来轻松修复。编辑其实我会自己改变它因为它让我烦恼:-)

#2


13  

Since your tags include jQuery, here's what I would do in jQuery, with heavy inspiration from this related answer:

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

function preloadImages(images, callback) {
    var count = images.length;
    if(count === 0) {
        callback();
    }
    var loaded = 0;
    $(images).each(function() {
        $('<img>').attr('src', this).load(function() {
            loaded++;
            if (loaded === count) {
                callback();
            }
        });
    });
};

// use whatever callback you really want as the argument
preloadImages(["a.gif", "b.gif", "c.gif"], function() {
    alert("DONE");
});

This relies on the callback to jQuery's load function.

这依赖于对jQuery的加载函数的回调。

I wouldn't use the related answer simply because I don't like mucking around with Javascript's built-in prototypes.

我不会仅仅因为我不喜欢使用Javascript的内置原型来使用相关的答案。

#3


1  

I've seen something used to correct behavior on Masonry nice jQuery plugin (a plugin used to make nice layout composition on pages). This plugin had problems with blocks containing images and should delay his work when the images are loaded.

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

First solution is to delay on the onLoad event instead of document.ready. But this event can be quite long to wait for. So they use jquery.imagesloaded.js which can detect that all images in a div are loaded; especially this very short and nice code can handle cached images which does not fire the load event sometimes.

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

#4


0  

Check out: http://engineeredweb.com/blog/09/12/preloading-images-jquery-and-javascript. It uses jQuery. In the comments, your direct issue is addressed by someone and a solution was posted there. I think it'll fit your needs.

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

#5


0  

As an alternative you could use a CSS technique to pre-load the images as shown here:

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

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

and then use the global onLoad event which is fired when everything has been loaded

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

#6


0  

//Here is a pre-jquery method, but jquery is bound to be simpler to write.

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

#7


0  

I'm searching for techniques that work for doing this all day now, and I finally found the solution to all my problems: https://github.com/htmlhero/jQuery.preload

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

It can even preload sequentially for you, in batches of any size (two at a time, for example), and fire a callback each time a batch completes.

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

#8


0  

jquery preloading multiple images serially can be done with a callback.

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

For example:

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

#9


0  

Based on answer from Ben Clayton above.

基于Ben Clayton的回答。

There can be case where images load fail all together and one must still be able to get callback.

可能存在图像加载一起失败并且仍然必须能够进行回调的情况。

Here is my revised answer. One ca easily find out hom many images loaded with success and how many ended up in error. this in callback will have that info

这是我修改后的答案。一个人很容易发现很多图像加载成功,有多少图像最终出错。回调中的这个将有这些信息

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/

// 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);
  });
};

#10


0  

Today I needed to preload images and execute some code only after all images are loaded, but without jQuery and using Ionic2/Typescript2. Here's my solution:

今天我需要预先加载图像并在加载所有图像后执行一些代码,但是没有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>) {
        ...
      }
      ...
 }

You can use like this. Problematic url returns 'null'.

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

loadImages(['https://cdn2.iconfinder.com/data/icons/nodejs-1/512/nodejs-512.png', 'http://foo_url'])
.then(function(arr) {
   console.log('[???]', arr); 
})