Display a Loading icon while images loads

15,125

Solution 1

Create a component that shows the placeholder image until the requested image is loaded, and hides the requested image. Once the image is loaded, you hide the placeholder and show the image.

@Component({
  selector: 'image-loader',
  template: `<img *ngIf="!loaded" src="url-to-your-placeholder"/>
    <img [hidden]="!loaded" (load)="loaded = true" [src]="src"/>`
})
export class ImageLoader {
  @Input() src;
}

See it working in Plunker.

Update

Now that I understand the requirements better, here's a solution with background image. It's a little hacky, and I like the original one better...

@Directive({
  selector: '[imageLoader]'
})
export class ImageLoader {
  @Input() imageLoader;

  constructor(private el:ElementRef) {
    this.el = el.nativeElement;
    this.el.style.backgroundImage = "url(http://smallenvelop.com/demo/image-loading/spinner.gif)";
  }

  ngOnInit() {
    let image = new Image();
    image.addEventListener('load', () => {
      this.el.style.backgroundImage = `url(${this.imageLoader})`;
    });
    image.src = this.imageLoader;
  }
}

Updated plunker.

Solution 2

Here is a copy of one of my posts

I finally solved that problem with CSS! When an image is loading in ionic 2, the ion-img tag doesn't have any class. However, when the image is finally loaded, the ion-img tag get the class "img-loaded".

Here is my solution :

  <ion-img [src]="img.src"></ion-img>
  <ion-spinner></ion-spinner>

And my CSS :

.img-loaded + ion-spinner {
  display:none;
}
Share:
15,125

Related videos on Youtube

Folky.H
Author by

Folky.H

Updated on June 04, 2022

Comments

  • Folky.H
    Folky.H almost 2 years

    I want to show a background image/loading spinner inside a div that will load an image inside of it, the image will show once it's fully loaded doing something like this:

       <div style="background-image:url('imageThatWillAppearBeforeLoad')"></div>
    

    Demo (In jQuery)

    How can I have the same using Angular2/Ionic2?

  • Folky.H
    Folky.H almost 8 years
    Your code is working fine, but for my case as I've posted, I've a <div style="background-image:url('imageThatWillAppearBeforeLoad')‌​"></div> that contains an image in background, I've tried to tweak your code to match the div I have but It didn't worked, Is it possible to make it work as a div ?
  • Folky.H
    Folky.H almost 8 years
    For what I achieved so far I guess that (load) does not work for some reason! Because I've replaced the img with div, etc... when I go to check the DOM, I see hidden which means that loaded = true was not applied for some reason, what makes me even sure that there is an issue with (load) is that I replace it with (click) then I place it in the placeholder div and it worked! So, do you have any idea why (load) didn't worked?
  • Yaron Schwimmer
    Yaron Schwimmer almost 8 years
    It didn't work because divs don't have an onload event... This is why I made the component that way.
  • Yaron Schwimmer
    Yaron Schwimmer almost 8 years
    Does it have to be a div? Do you need the requested image also as a background-image, or can that be a img element?
  • Folky.H
    Folky.H almost 8 years
    It needs to be a div not img
  • Folky.H
    Folky.H almost 8 years
    that's the thing I need it as background-image
  • Folky.H
    Folky.H almost 8 years
    it shows both, the loader and the image, check please the plunker
  • Yaron Schwimmer
    Yaron Schwimmer almost 8 years
  • Folky.H
    Folky.H almost 8 years
    I ended up switching to the img tag, now everything works well!! Thank you for all the efforts +1
  • Siyah
    Siyah over 5 years
    How can we do this for Ionic 1?
  • Ronin
    Ronin over 3 years
    While this solution works (updated version), the directive triggers 2 separate GET calls. After debugging I can confirm that both this.el.style.backgroundImage = url(${this.imageLoader}); and image.src = this.imageLoader; each trigger 1 call respectively. Is there any solution which prevents from sending the GET request for the image twice?