Best way to preload images with Angular.js

前端 未结 9 881
野性不改
野性不改 2020-12-07 16:04

Angular\'s ng-src keeps previous model until it preloads image internally. I am using different image for the banner on each page, when I switch routes, i change main view,

相关标签:
9条回答
  • 2020-12-07 16:26

    Having the 2 urls on the directive seems a touch overcomplicated. What I think is better is to write a directive that works like:

    <img ng-src="{{bannerUrl}}" spinner-on-load />
    

    And the directive can watch ng-src and (for example) set visibility:false with a spinner until the image has loaded. So something like:

    scope: {
      ngSrc: '='
    },
    link: function(scope, element) {
      element.on('load', function() {
        // Set visibility: true + remove spinner overlay
      });
      scope.$watch('ngSrc', function() {
        // Set visibility: false + inject temporary spinner overlay
      });
    }
    

    This way the element behaves very much like a standard img with an ng-src attribute, just with a bit of extra behaviour bolted on.

    http://jsfiddle.net/2CsfZ/47/

    0 讨论(0)
  • 2020-12-07 16:28

    A simple solution I've found is to change the url to '//:0' before assigning it's new value

    $scope.bannerUrl = 'initial value'; 
    
    // When we want to change it
    $scope.bannerUrl = '//:0';  // remove the previous img so it's not visible while the new one loads
    $scope.bannerUrl = scope.preloadedUrl
    
    0 讨论(0)
  • 2020-12-07 16:32

    If anyone is interested this is my final solution: I use twitter bootstrap. So added class of "fade" to all images and just toggling class "in" with directive to fade in and out when image is loaded

    angular.module('myApp').directive('imgPreload', ['$rootScope', function($rootScope) {
        return {
          restrict: 'A',
          scope: {
            ngSrc: '@'
          },
          link: function(scope, element, attrs) {
            element.on('load', function() {
              element.addClass('in');
            }).on('error', function() {
              //
            });
    
            scope.$watch('ngSrc', function(newVal) {
              element.removeClass('in');
            });
          }
        };
    }]);
    
    <img img-preload class="fade" ng-src="{{imgSrc}}">
    

    Working example: http://ishq.org

    0 讨论(0)
  • 2020-12-07 16:32

    Just to share ^^

     //css
    .media-box{
                    position: relative;
                    width:220px;
                    height: 220px;
                    overflow: hidden;
                }
                .media-box div{
                    position: absolute;
                    left: 0;
                    top: 0;
                }
                .spinner{
                    position: absolute;
                    left: 0;
                    top: 0;
                    background: #CCC url(./spinner.gif) no-repeat center center;
                    display: block;
                    width:220px;
                    height: 220px;
                }
                .feed img.spinner-show{
                    visibility: visible;
                }
                .feed img.spinner-hide{
                    visibility: hidden;
                }
    
    //html
    <div class="media-box">
      <div>
        <img data-ng-src="{{item.media}}" alt="" title="" data-spinner-on-load>
      </div>
    </div>
    
    //js
    .directive('spinnerOnLoad', function() {
                return {
                    restrict: 'A',
                    link: function(scope,element){
                        element.on('load', function() {
                            element.removeClass('spinner-hide');
                            element.addClass('spinner-show');
                            element.parent().find('span').remove();
                        });
                        scope.$watch('ngSrc', function() {
                            element.addClass('spinner-hide');
                            element.parent().append('<span class="spinner"></span>');
                        });      
                    }
                }
            });
    
    0 讨论(0)
  • 2020-12-07 16:35

    images can be preloaded on route change by using image-preloader factory and resolve:

    // call REST
                        return getContent.get().$promise.then(function(response) {
    
                                    //return response;
    
                                    // preload images from response
                                    var imageLocations = [
                                      // put image(s) from response to array
                                      response.PostImage.big[0],
                                    ];
    
                                    // check do we have (all) image(s) in array
                                    console.log(imageLocations);
    
                                    // return when all images are preloaded
                                    return preloader.preloadImages( imageLocations )
                                    .then(function() {
    
                                        //if it was success 
                                        return response;
                                    },
                                    function() {
    
                                            //if it failed 
                                        return response;
                                    });
    
                                });
    

    complete tutorial here: https://www.coditty.com/code/angular-preload-images-on-route-change-by-using-resolve

    0 讨论(0)
  • 2020-12-07 16:39

    I have this directive which shows a spinner when img-src changes:

    <img-with-loading
          img-src="{{src}}"
          spinner-class="{{spinnerClass}}"
    />
    

    Code here: http://jsfiddle.net/ffabreti/yw74upyr/

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