Intersection Observer дважды запускает обратный вызов на ngAfterViewInit

Я попытался отложить загрузку изображений с помощью Intersection Observable в моем приложении angular 7. Я вызвал Intersection Observable из ловушки жизненного цикла ngAfterViewInit. Но когда я загружаю приложение, обратный вызов вызывается дважды: один раз со всеми значениями isIntersecting как истинными, а следующий - с правильными значениями isIntersecting. Меня смущает такое поведение.

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

ОБНОВЛЕНИЕ: теперь наблюдатель пересечения вызывается отлично, но теперь возникла проблема. Поскольку мы используем document.querySelectorAll, который возвращает статический список узлов, после обновления массива список узлов не обновляется. Если я попытаюсь использовать document.getElementsByClassName, выдается ошибка, поскольку это не список узлов ???


person Ram    schedule 10.09.2019    source источник
comment
Вы пробовали таким способом observer.observe(imgOne);, нет необходимости в foreach.   -  person Shohel    schedule 10.09.2019
comment
Используйте класс в queryselector, а не атрибут данных observer.observe(document.querySelectorAll('img.lzy_img'));   -  person Shohel    schedule 10.09.2019
comment
Будет выдана ошибка: «Аргумент типа« NodeListOf ‹Element› »не может быть назначен параметру типа« Element ». поскольку наблюдение получает в качестве аргумента единственный элемент, а не массив элементов.   -  person Ram    schedule 10.09.2019
comment
Создайте пример для stackblitz   -  person Shohel    schedule 11.09.2019
comment
stackblitz.com/edit/angular-wqbuyr   -  person Ram    schedule 12.09.2019
comment
Теперь я заставил его работать, но теперь проблема, когда я увеличиваю счетчик массива, наблюдатель не принимает новый массив ???   -  person Ram    schedule 12.09.2019
comment
Я решил проблему, удалив ngOnInit (), так как он снова запускал ngAfterViewInit () после загрузки.   -  person Ram    schedule 14.09.2019
comment
Очень интересно, ваш вопрос ...   -  person Shohel    schedule 14.09.2019


Ответы (2)


Возможно, это тоже работает:

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

Если вы не проверяете correctionRatio ratio === 1, наблюдаемый элемент вызовет обратный вызов дважды, потому что при немедленном прохождении / выходе из 100% порога наблюдатель сработает isIntersecting = true, correctionRatio ~ = 0.9 (возможно, ошибка). Каким-то образом Chrome получает значение correctionRatio немного выше 1 в первом поле, поэтому уменьшите значение

Источник: https://codepen.io/mmanney/details/erpZbd

person Washington Braga    schedule 30.11.2020

Я решил проблему, удалив ngOnInit (), так как он снова запускал ngAfterViewInit () после загрузки.

person Ram    schedule 22.10.2019