2

// Code goes here

angular
  .module('imgapp', [])
  .controller('mainCtrl', mainCtrl);
  
function mainCtrl() {
  var vm = this;
  
  vm.first = {
    title: 'Image 1',
    url: 'http://www.image-mapper.com/photos/original/missing.png'
  }
  
  vm.second = {
    title: 'Image 2',
    url: 'http://www.keenthemes.com/preview/conquer/assets/plugins/jcrop/demos/demo_files/image1.jpg'
  }
  
  vm.primary = vm.first;
  
  vm.changeObject = function() {
    vm.primary = vm.second;
  }
}
<html ng-app="imgapp">
  <head>
    <script data-require="angular.js@1.4.9" data-semver="1.4.9" src="https://code.angularjs.org/1.4.9/angular.js"></script>
    <script src="script.js"></script>
  </head>

  <body ng-controller="mainCtrl as vm">
    <button ng-click="vm.changeObject();">Change object</button>
    <h1>{{vm.primary.title}}</h1>
    <img ng-src="{{vm.primary.url}}">
  </body>
</html>

I have a block with a title and an image in it. Data in this block can be changed, therefore another image should be loaded.
If you have slow internet connection, you can see that the title was changed, where image wasn't, cause it hasn't loaded yet.

Demo: (press change object to load a new image and change the title)

How can I hide an old image until a new image has been loaded?

Note: I don't use jQuery

itzmukeshy7
  • 2,669
  • 1
  • 21
  • 29
Michael
  • 15,386
  • 36
  • 94
  • 143
  • possible duplicate http://stackoverflow.com/questions/51352/how-to-show-a-spinner-while-loading-an-image-via-javascript – Lucas Mar 14 '16 at 10:21

4 Answers4

3

Working demo

I have just created a directive which will call a function upon image load.

.directive('imageonload', function() {
    return {
        restrict: 'A',
        scope: {
          ngShow : '='
        },
        link: function(scope, element, attrs) {
            element.bind('load', function() {
                alert('image is loaded');
                scope.$apply(function(){
                    scope.ngShow = true;  
                });

            });
            element.bind('error', function(){
                alert('image could not be loaded');
            });
        }
    };
});

And modified html like,

<img ng-show="vm.isImageVisible" ng-src="{{vm.primary.url}}" imageonload >
Abhilash Augustine
  • 4,128
  • 1
  • 24
  • 24
0

I believe you're looking for ng-cloak directive: https://docs.angularjs.org/api/ng/directive/ngCloak

So your example can look like this:

<body ng-controller="mainCtrl as vm">
  <button ng-click="vm.changeObject();">Change object</button>
  <div ng-cloak>
    <h1>{{vm.primary.title}}</h1>
    <img ng-src="{{vm.primary.url}}">
  </div>
</body>

http://plnkr.co/edit/rf8hM9JvR7EnjS1eWOgp?p=preview

Piotr Czarnecki
  • 1,688
  • 3
  • 14
  • 22
0

This may help you:

var image = imageDomReferenceHere;
var downloadingImage = new Image();
downloadingImage.onload = function(){
   image.src = this.src;   
};
downloadingImage.src = "image path here";

http://blog.teamtreehouse.com/learn-asynchronous-image-loading-javascript

itzmukeshy7
  • 2,669
  • 1
  • 21
  • 29
0

You can do it with two steps. First add ng-show to hide or show element when it is loading. Second use onLoad event to know when it is done loading. I picked directive from this answer

html

vm.notLoading = true;
vm.imageLoaded = imageLoaded;

directive

function imageonload() {
    return {
    restrict: 'A',
    link: function(scope, element, attrs) {
        element.bind('load', function() {
            //call the function that was passed
            scope.$apply(attrs.imageonload);
        });
    }
}

controller

...

vm.notLoading = true;
vm.imageLoaded = imageLoaded;

...

vm.changeObject = function() {
    vm.notLoading = false;
    vm.primary = vm.second;
}

function imageLoaded() {
    vm.notLoading = true;
}

plunker

Community
  • 1
  • 1
Mike Kor
  • 876
  • 5
  • 14