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

Time:09-08

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  [defaultImage]="defaultImage" [lazyLoad]="image"/>
  <ngx-skeleton-loader #skeleton  [theme]="{ height: '100%', 'margin-bottom': '0' }"></ngx-skeleton-loader>

And i would do something like:

  <img #productImage  *ngIf="productImage.classList.contains('ng-lazyloaded'); else skeleton" [defaultImage]="defaultImage" [lazyLoad]="image"/>
  <ngx-skeleton-loader #skeleton  [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" 
        [defaultImage]="defaultImage" [lazyLoad]="image" />
          <ng-template #skeleton>
        <ngx-skeleton-loader  [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.

CodePudding user response:

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" 
        [defaultImage]="defaultImage" [lazyLoad]="image" />
          <ng-template #skeleton>
        <ngx-skeleton-loader  [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" 
            [defaultImage]="defaultImage" [lazyLoad]="image" />
              <ng-template #skeleton>
            <ngx-skeleton-loader  [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