Ng-lazyload-image: How can I manually trigger the loading of images?

Created on 25 Aug 2017  ·  11Comments  ·  Source: tjoskar/ng-lazyload-image

I am using ng-lazyload-image in a filterable collection. It works fine when scrolling, but when I filter the list, the thumbnails are not appearing. Thats happening because no scroll event is fired. After scrolling a bit they appear.

Demo

loading

Workaround

I found a hacky workaround, but I'm not happy with it…

// -1, +1 is there to fire the scroll event. Otherwise chrome/ff wont fire it.
window.scrollTo(window.scrollX, window.scrollY - 1);
window.scrollTo(window.scrollX, window.scrollY + 1);
question

Most helpful comment

Hi @philipgiuliani,

The problem is that ng-lazyload-image only checks if the image is in the viewport when the user scrolls. As long there is no scroll event, ng-lazyload-image will not do anything.

So in order to solve your use case we need to let ng-lazyload-image know that the world around it has changed. There are two ways of doing that:

  1. Firing a scroll event. This will trick ng-lazyload-image to revalidate if the images are in the viewport or not. But his solution is not pretty (as you hinted).
  2. Creating your own stream with scroll events and merge with your custom events:
// In your component

constructor() {
  this.updateSearchResult$ = new Subject();
  this.scrollAndSearch$ = Observable.merge(
    Observable.fromEvent(window, 'scroll')
    this.updateSearchResult$
  );
}

onSerachResultResponse() {
  this.updateSearchResult$.next()
}
// in your template
<img [lazyLoad]="lazyLoadImage" [customObservable]="scrollAndSearch$" />

Did this answer your question?

All 11 comments

Hi @philipgiuliani,

The problem is that ng-lazyload-image only checks if the image is in the viewport when the user scrolls. As long there is no scroll event, ng-lazyload-image will not do anything.

So in order to solve your use case we need to let ng-lazyload-image know that the world around it has changed. There are two ways of doing that:

  1. Firing a scroll event. This will trick ng-lazyload-image to revalidate if the images are in the viewport or not. But his solution is not pretty (as you hinted).
  2. Creating your own stream with scroll events and merge with your custom events:
// In your component

constructor() {
  this.updateSearchResult$ = new Subject();
  this.scrollAndSearch$ = Observable.merge(
    Observable.fromEvent(window, 'scroll')
    this.updateSearchResult$
  );
}

onSerachResultResponse() {
  this.updateSearchResult$.next()
}
// in your template
<img [lazyLoad]="lazyLoadImage" [customObservable]="scrollAndSearch$" />

Did this answer your question?

I was searching for a solution to a similar problem, and want to share it, because I suspect this issue is where people will probably find it.

Problem: load images after a delay, even if they are not visible within the offset
Solution: instead of a fixed offset, create an Observable for offset values, and set a really high offset after the desired time

// in the Angular 2+ component
constructor () {
  this.imageLoadOffset$ = Observable.merge(
    Observable.of(300),                 // initial offset
    Observable.of(100000).delay(5000)   // offset triggering loading after 5 seconds
  );
}
// in the template
<img [lazyLoad]="'foo.png'" [offset]="imageLoadOffset$ | async" />

Thanks for your contribution, I added a link to this issue in the readme file.

当我快速滚动容器后,滚动过去的图像不加载,滚动结束后,加载当前视口的图片,怎么做??

@pangshangggg, sorry but I don't understand. I tried to use google translate but I did not understand your question :/ is it possible for you to write in English?

In Ionic 2/3, the images don't load until the user start scrolling. You can solve this in two ways:
The ugliest way is like this :

@ViewChild(Content) container: Content;
ionViewDidEnter() {
      this.container.scrollTo(this.container.scrollLeft, this.container.scrollTop + 1);
      this.container.scrollTo(this.container.scrollLeft, this.container.scrollTop - 1);
   }

And this is the good way :

@ViewChild(Content) container: Content;
contentLoaded: Subject<any> = new Subject();
loadAndScroll: Observable<any>;

ionViewDidEnter() {
      this.contentLoaded.next();
}
ionViewDidLoad() {
      this.loadAndScroll = Observable.merge(
         this.container.ionScroll,
         this.contentLoaded
      );
}

(in the template : [customObservable]="loadAndScroll" )

I just transposed the solutions posted above to ionic. Nothing more :)

In Angular 6 and rxjs 6, I'm trying to trigger manually the lazy load by scroll event by following the previous examples but it's not working. All the images are loading one after another without scrolling the page. This is my code.

Template:

<div *ngFor="let image of images">
    <img [defaultImage]="defaultImage"
    [lazyLoad]="image"
    [useSrcset]="true"
    [offset]="offset" [scrollObservable]="scrollObservable" >
</div>

component:
scrollObservable = fromEvent(window, 'scroll');

I followed this example from issue 224 where el-Davo said that this fixes the problem in Angular 5

In Ionic 2/3, the images don't load until the user start scrolling. You can solve this in two ways:
The ugliest way is like this :

@ViewChild(Content) container: Content;
ionViewDidEnter() {
      this.container.scrollTo(this.container.scrollLeft, this.container.scrollTop + 1);
      this.container.scrollTo(this.container.scrollLeft, this.container.scrollTop - 1);
   }

And this is the good way :

@ViewChild(Content) container: Content;
contentLoaded: Subject<any> = new Subject();
loadAndScroll: Observable<any>;

ionViewDidEnter() {
      this.contentLoaded.next();
}
ionViewDidLoad() {
      this.loadAndScroll = Observable.merge(
         this.container.ionScroll,
         this.contentLoaded
      );
}

(in the template : [scrollObservable]="loadAndScroll" )

I just transposed the solutions posted above to ionic. Nothing more :)

sorry but i have a problem.
this.contentLoaded.next();
not working
It works fine only when scrolling
???

Hi @zarinara,
When you say not working, do you get any errors?

Hi
No errors occurs

@zarinara, can you create a new issue and include some code examples and the version number of ng-lazyload-image (npm ls ng-lazyload-image). Is it possible for you to use intersectionObserver?

Was this page helpful?
0 / 5 - 0 ratings

Related issues

dkmostafa picture dkmostafa  ·  7Comments

AzerHeshim picture AzerHeshim  ·  5Comments

sandeepdussa picture sandeepdussa  ·  9Comments

vugar005 picture vugar005  ·  10Comments

coryrylan picture coryrylan  ·  7Comments