Show loading gif while image is loading

Angular 8 Solution with Hostlistener and Hostbinding.

1. Create a simple attribute directive

import { Directive, HostListener, Input, HostBinding } from '@angular/core';
@Directive({selector: '[imageLoader]'})
export class ImageLoaderDirective
{
  @Input('src') imageSrc;
  @HostListener('load')
  loadImage()
  {
  this.srcAttr=this.imageSrc;
  }

@HostBinding('attr.src') srcAttr="../../assets/pics/Loader.svg"
constructor() { }
}

Basically we set the initial image source to the loader image. Once the image loads(load event triggered), we listen to it and set the image source to the actual image.

2. Now use the just need to use the created attributes on your images.

<img imageLoader src='image.jpg'>

Using svg requires no styling changes, gif may require css changes.

You can visit the website for working implementation.


You can set the background of an image to the loading gif. It is a simple css trick. You wouldn't need then to make a js script.

.loading {
  background: transparent url('http://thinkfuture.com/wp-content/uploads/2013/10/loading_spinner.gif') center no-repeat;
}
<img class="loading" src="http://placehold.it/106&text=1" width="106px" height="106px" />
<img class="loading" src="http://placehold.it/106&text=2" width="106px" height="106px" />
<img class="loading" src="http://placehold.it/106&text=3" width="106px" height="106px" />
<img class="loading" src="http://placehold.it/106&text=4" width="106px" height="106px" />
<img class="loading" src="http://placehold.it/106&text=5" width="106px" height="106px" />
<img class="loading" src="http://placehold.it/106&text=6" width="106px" height="106px" />
<img class="loading" src="http://placehold.it/106&text=7" width="106px" height="106px" />

Update :

In case you have transparent images then the story becames a bit more complicated but, still can be done with css and some div elements.

.image-wrapper {
  overflow: hidden;
  width: 106px;
  height: 106px;
  display: inline-block;
}

.image-wrapper img {
  float: left;
  display: block;
  opacity: 0.2; /* simulating a semitransparent image */
}

.image-wrapper:after, .loading {
  content: ' ';
  background: transparent url('http://thinkfuture.com/wp-content/uploads/2013/10/loading_spinner.gif')  center no-repeat ;
  background-size : auto 100%;
  width: 106px;
  height: 106px;
  float: left;
  display: block;
}
<div class="image-wrapper">
  <!-- simulates a hard loading image -->
  <img src="http://placehold.it/not-existing" alt="" />
</div>
<div class="image-wrapper">
  <img src="http://placehold.it/106x106&text=2" alt="" />
</div>
<div class="image-wrapper">
  <img src="http://placehold.it/106x106&text=3" alt="" />
</div>
<div class="image-wrapper">
  <img src="http://placehold.it/106x106&text=4" alt="" />
</div>
<div class="image-wrapper">
  <img src="http://placehold.it/106x106&text=5"  alt="" />
</div>
<div class="image-wrapper">
  <img src="http://placehold.it/106x106&text=6"  alt="" />
</div>
<div class="image-wrapper">
  <img src="http://placehold.it/106x106&text=7"  alt="" />
</div>

Unfortunately the browser adds a broken icon or a ? while loading, this is why the image contains an empty alt;

Update 2 :

The second variant relies very much on the image size, if you have difrent sizes than the loading gif won't be pushed away properly, as an alternative would be to use the first variant and a little js script that will remove the background as soon as the image is loaded:

$('img').load(function(){
   $(this).css('background','none');
});
   .loading {
      background: transparent url('http://thinkfuture.com/wp-content/uploads/2013/10/loading_spinner.gif') center no-repeat;
    }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<img class="loading" src="http://upload.wikimedia.org/wikipedia/en/2/2d/SRU-Logo-Transparent.png" width="106px" height="106px" />
    <img class="loading" src="http://placehold.it/106&text=2" width="106px" height="106px" />
    <img class="loading" src="http://placehold.it/106&text=3" width="106px" height="106px" />
    <img class="loading" src="http://placehold.it/106&text=4" width="106px" height="106px" />
    <img class="loading" src="http://placehold.it/106&text=5" width="106px" height="106px" />
    <img class="loading" src="http://placehold.it/106&text=6" width="106px" height="106px" />
    <img class="loading" src="http://placehold.it/106&text=7" width="106px" height="106px" />