Fire an event after preloading images

前端 未结 10 1848
北海茫月
北海茫月 2020-12-25 15:25

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

相关标签:
10条回答
  • 2020-12-25 15:46

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

    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
    });
    
    0 讨论(0)
  • 2020-12-25 15:49

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

    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;
    }
    
    0 讨论(0)
  • 2020-12-25 15:53

    Since your tags include jQuery, here's what I would do in jQuery, with heavy inspiration from 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");
    });
    

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

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

    0 讨论(0)
  • 2020-12-25 15:54

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

    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

    0 讨论(0)
  • 2020-12-25 15:56

    Based on answer from Ben Clayton above.

    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/

    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);
      });
    };
    
    0 讨论(0)
  • 2020-12-25 16:00

    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

    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.

    0 讨论(0)
提交回复
热议问题