How to show skeleton while ng-lazyload-image is loading by checking if current dom has class?

Viewed 51

I'm using ng-lazyload-image to lazy load images in my Angular project, i would be able to show a skeleton while the image is loading, i'm yet using ngx-skeleton-loader.

To show the skeleton i tought to check if the image has ng-lazyloaded class in it as it's the only way to know if the image is still loading or not.

My code looks like this:

  <img class="image-cover" [defaultImage]="defaultImage" [lazyLoad]="image"/>
  <ngx-skeleton-loader #skeleton class="image-cover" [theme]="{ height: '100%', 'margin-bottom': '0' }"></ngx-skeleton-loader>

And i would do something like:

  <img #productImage class="image-cover" *ngIf="productImage.classList.contains('ng-lazyloaded'); else skeleton" [defaultImage]="defaultImage" [lazyLoad]="image"/>
  <ngx-skeleton-loader #skeleton class="image-cover" [theme]="{ height: '100%', 'margin-bottom': '0' }"></ngx-skeleton-loader>

But how can i check if img has ng-lazyloaded? If i try to use .classList on productImage i just get that it doesn't exists.

PS: the upper code is just like "pseudo-code", it's just an idea.

I've tried even this:

      <img #productImage *ngIf="hasLoaded(); else skeleton" class="image-cover"
        [defaultImage]="defaultImage" [lazyLoad]="image" />
          <ng-template #skeleton>
        <ngx-skeleton-loader class="image-cover" [theme]="{ height: '100%', 'margin-bottom': '0' }">
        </ngx-skeleton-loader>
      </ng-template>

  @ViewChild('productImage') productImage: ElementRef;

  hasLoaded() {
    if (this.productImage?.nativeElement.classList.contains('ng-lazyloaded')) {
      return false;
    }else {
      return true;
    }
  }

But all skeletons are set to invisible once the first image is loaded.

1 Answers

Because ViewChild can take only one element at a time so you are getting the issue, instead check each element ref with the same code you wrote, then you can check for each one individually!

 <img #productImage *ngIf="!productImage?.classList.contains('ng-lazyloaded'); else skeleton" class="image-cover"
        [defaultImage]="defaultImage" [lazyLoad]="image" />
          <ng-template #skeleton>
        <ngx-skeleton-loader class="image-cover" [theme]="{ height: '100%', 'margin-bottom': '0' }">
        </ngx-skeleton-loader>
      </ng-template>

or you could try to pass it as a function which returns true or false!

<img #productImage *ngIf="checkIfLazy(productImage); else skeleton" class="image-cover"
            [defaultImage]="defaultImage" [lazyLoad]="image" />
              <ng-template #skeleton>
            <ngx-skeleton-loader class="image-cover" [theme]="{ height: '100%', 'margin-bottom': '0' }">
            </ngx-skeleton-loader>
          </ng-template>

ts

checkIfLazy(productImage: any) {
    const productImageElement: any = productImage && productImage.nativeElement ? productImage.nativeElement : productImage;
    return !productImageElement?.classList.contains('ng-lazyloaded');
}
Related