Выполнить код, если элемент попал в поле видимости

Выполнять код, если объект попал в поле видимости, можно через объект IntersectionObserver.

const observer = new IntersectionObserver(callback),
      lazyImages = document.querySelectorAll('.lazy-image');

// выполнять код, когда картинки попадают в поле зрения
lazyImages.forEach((image) => observer.observe(image));

const callback = (entries, observer) => {
  entries.forEach((entry) => {
    // объект попадает в поле зрения браузера
    if (entry.isIntersecting) {
      console.log("Объект попал в поле видимости");

      // прекратить отслеживать
      observer.unobserve(entry.target)
    }
  })
}

В коде выше указано, если объект с классом «lazy-image» попадёт в поле видимости, то выполнять функцию «callback».

Если выполнение «Intersection Observer» больше не нужно, то в целях оптимизации рекомендуется отключать через код ниже:

observer.disconnect();

Выполнять код, если объект полностью или наполовину попал в поле видимости

По умолчанию, «Intersection Observer» выполняется только один раз, когда объект попадает в поле видимости.

Если надо сделать, чтобы код выполнялся в ситуациях, когда объект виден на половину или полностью, то это задаётся через свойство threshold:

const options = {
  threshold: [0, 0.5, 1]
}

const observer = new IntersectionObserver(callback, options);

На примере выше задано, чтобы код выполнялся в трёх ситуациях:

  • 0 — объект попал в поле видимости;
  • 0.5 — объект виден на половину;
  • 1 — объект виден полностью.

Тут стоит обратить внимание, что это именно степень видимости объекта, а не процент прокрутки.

Отследить текущую область видимости можно через параметр intersectionRatio.

const options = {
  threshold: [0, 0.5, 1]
}

const observer = new IntersectionObserver(callback, options),
      lazyImages = document.querySelectorAll('.lazy-image');

lazyImages.forEach((image) => observer.observe(image));

const callback = (entries, observer) => {
  entries.forEach(({isIntersecting, intersectionRatio}) => {
    // объект попадает в поле зрения браузера
    if (isIntersecting) {

      if (intersectionRatio >= 0 && intersectionRatio < 0.45) {
        console.log("Элемент появился в области наблюдения");
      }

      if (intersectionRatio >= 0.45 && intersectionRatio < 0.75) {
        console.log("Элемент наполовину в области наблюдения");
      }

      if (intersectionRatio === 1) {
        console.log("Элемент полностью в области наблюдения");
      }

    }
  })
}