Javascript 预加载图像

Javascript 预加载图像,javascript,angularjs,Javascript,Angularjs,在我的视图解析之前,我想在Angular中预加载图像。我使用的是ui路由器,所以我假设它看起来像这样: $stateProvider .state('home', { url: '/', templateUrl: './views/home.html', controller: 'homeCtrl', resolve : { Images : ['Images', function(Images)

在我的视图解析之前,我想在Angular中预加载图像。我使用的是ui路由器,所以我假设它看起来像这样:

 $stateProvider
    .state('home', {
        url: '/',
        templateUrl: './views/home.html',
        controller: 'homeCtrl',
        resolve : {
            Images : ['Images', function(Images) {
                return Images.preload();
            }]
        }
    })

Images.preload()
中,我想预先设置图像对象,这样在状态解析后它就可以使用了

我编写了一个图像预加载服务,您可以将其用作解析函数的一部分,然后使用“finished”回调进行解析

projector.factory('imagePreloader', function() {
  var service = {};


  /**
   * To use the service, inject it into your controller then call:
   *
   * imagePreloader.preLoadImages with the following paremeters
   *
   * @param images - a flat array of image URL's
   * @param strategy - "linear" or "parallel" - linear will load one image at a time in the order they appear in the array. Parallel
   *                    will attempt to load all images at once
   * @param finish_cb - function() - the success callback
   * @param status_cb - function(percent_complete, imageDomelement) - a status function that fires after each image has been loaded
   * @param error_cb - function(err) - error handler that will trigger for any errors
   */

  service.preLoadImages = function(images, strategy, finish_cb, status_cb, error_cb) {

    var image_cnt = images.length;
    var loaded_cnt=0;

    var error_handler = function(err) {
      if (typeof(error_cb) == 'function') {
        error_cb( err );
      }
    }

    if (strategy == 'linear') {

      var loadImage;
      var loadImage = function() {

        var image_loaded_cb = function(ev) {
          loaded_cnt++;

          if (typeof(status_cb) == 'function') {
            status_cb( ~~(100 * loaded_cnt / image_cnt), ev.path[0] );
          }

          if (images.length > 0) {
            next();
          }

          if (loaded_cnt == image_cnt) {
            finish_cb();
          }

        }

        var next = function() {
          var imgUrl = images.shift();
          var image = angular.element(new Image()).bind('load', image_loaded_cb )
            .bind('error', error_handler)
            .attr('src', imgUrl)
        }
        next();

      }();

    } else if (strategy =='parallel') {

      var image_loaded_cb = function(ev) {
        loaded_cnt++;
        if (typeof(status_cb) == 'function') {
          status_cb( ~~(100 * loaded_cnt / image_cnt), ev.path[0] );
        }

        if (loaded_cnt == image_cnt) {
          finish_cb();
        }
      }

      angular.forEach(images, function(imgUrl) {

        var image = angular.element(new Image()).bind('load', image_loaded_cb )
          .bind('error', error_handler)
          .attr('src', imgUrl)

      });

    } else {
      throw new Error('Invalid strategy. Should either be "parallel" or "linear"')
    }
  }


  return service;
});
然后,要使用该服务,您可以像使用任何其他角度服务/工厂一样使用它:

app.controller('HomeController', function($scope, $http, $timeout, $location, imagePreloader) {



  //testing image preloader

  var images = [
    'https://www.google.com/images/srpr/logo11w.png',
    'https://s.yimg.com/pw/images/sohp_2014/trees_noblur.jpg',
    'http://i2.cdn.turner.com/cnnnext/dam/assets/130419165742-dzhokar-tsarnaev-vk-exlarge-169.jpg'];

  var status_cb = function(status_pct, img) { console.log('Done percent:', status_pct, img )};

  var finish_cb = function() { console.log("All done!"); }

  imagePreloader.preLoadImages(images, 'parallel', finish_cb, status_cb);

});

通常通过创建一个新映像
var a=new Image
并设置src
a.src='Image.jpg'