Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Intersection Observer triggering callback twice on ngAfterViewInit

I tried to lazy load images using Intersection Observable in my angular 7 application. I called Intersection Observable from ngAfterViewInit lifecycle hook. But when i load the application, callback is called twice, once with all the isIntersecting values as true and the next one with the correct isIntersecting values. I am confused with this behaviour.

ngAfterViewInit() {
const imgOne = document.querySelectorAll('[data-class]');

    const options = {
      // root: document
      // threshold: 0
    };

    const observer = new IntersectionObserver((entries, observer) => {
      console.log(entries.length);
      entries.forEach((entry) => {
        // console.log(entry);
        if (!entry.isIntersecting) {
          return;
        } else {
          const el = entry.target;
          if (el.id === ('test' + this.testCount)) {
            console.log(entry);
          }
          // observer.unobserve(entry.target);
        }
      });
    });

    imgOne.forEach((eachQuery) => {
      observer.observe(eachQuery);
    });
 }

https://stackblitz.com/edit/angular-wqbuyr

UPDATE : Now intersection observer is called perfectly, but now a issue occured. Since we are using document.querySelectorAll which returns a static node list, once the array is updted node list is not updated. If i try to use document.getElementsByClassName, an error throws as it is not an Node list ???

like image 821
Ram Avatar asked Sep 18 '25 15:09

Ram


1 Answers

Maybe this also works:

if (entry.isIntersecting && Math.floor(entry.intersectionRatio) === 1) { 
  const el = entry.target;
  if (el.id === ('test' + this.testCount)) {
    console.log(entry);
  }
} else {
  return;
}

"If you dont' check intersectionRatio ratio === 1, the observed element will trigger the callback twice, because when immediately passing/leaving 100% threshold, observer will trigger isIntersecting = true, intersectionRatio ~= 0.9 (maybe bug). Chrome somehow gets intersectionRatio slightly above 1 on the first box, so floor the value"

Source: https://codepen.io/mmanney/details/erpZbd

like image 163
Washington Braga Avatar answered Sep 21 '25 05:09

Washington Braga