Skip to content

Движок видимости

createVisibilityEngine(pool?) — оборачивает пулящийся IntersectionObserver определением стороны появления/исчезновения и поддержкой однократного срабатывания, без какой-либо реактивности, завязанной на фреймворк.

ts
function createVisibilityEngine(pool?: ObserverPool): VisibilityEngine

pool по умолчанию — общий синглтон observerPool (см. ниже) — передайте свой new ObserverPool(), чтобы изолировать обсерверы от остального приложения, что в основном полезно в тестах.

Возвращаемое значение

observe(element, options, callback)

(element: Element, options: VisibilityObserveOptions, callback: (info: IntersectionInfo) => void) => () => void

Начинает наблюдение за element. Возвращает функцию отписки.

destroy()

() => void

Выполняет все зарегистрированные функции отписки и очищает их.

VisibilityObserveOptions

ПолеТипПо умолчанию
rootElement | Document | nullnull
rootMarginstring'0px'
thresholdnumber | number[]0
oncebooleanundefined — при true observe() сам снимает наблюдение после первого isIntersecting: true.
onEnter(info: IntersectionInfo) => void— вызывается, когда info.edge равен 'enter-top' или 'enter-bottom'.
onLeave(info: IntersectionInfo) => void— вызывается, когда info.edge равен 'leave-top' или 'leave-bottom'.

IntersectionInfo

Передаётся в callback (и в onEnter/onLeave) при каждом изменении:

ПолеТипПримечание
isIntersectingboolean
intersectionRationumber
boundingClientRectDOMRectLike
edgeIntersectionEdge | undefined'enter-top' | 'enter-bottom' | 'leave-top' | 'leave-bottom' — устанавливается только когда isIntersecting отличается от предыдущего вызова.

Пример:

ts
import { createVisibilityEngine } from '@macrulez/inview-core'

const visibility = createVisibilityEngine()

const unobserve = visibility.observe(
  document.querySelector('#hero')!,
  { threshold: 0.5, once: true },
  (info) => {
    if (info.isIntersecting) console.log('наполовину видим')
  },
)

Пул обсерверов

ObserverPool / observerPool — пулит нативные инстансы IntersectionObserver по (root, rootMargin, threshold) — много элементов, наблюдаемых с одинаковыми опциями, используют один обсервер вместо того, чтобы каждый порождал свой. createVisibilityEngine() по умолчанию использует общий синглтон observerPool.

ts
class ObserverPool {
  observe(
    element: Element,
    options: ObserverPoolOptions,
    callback: (entry: IntersectionObserverEntry) => void,
  ): () => void
}

const observerPool: ObserverPool

ObserverPoolOptions — это { root?, rootMargin?, threshold? }, те же три поля, что выше, с теми же значениями по умолчанию (null/'0px'/0), применяемыми в момент, когда для данного ключа реально создаётся новый нативный IntersectionObserver. Пул отключает и убирает нативный обсервер, как только последний наблюдаемый им элемент снимает наблюдение. В окружении без IntersectionObserver вообще observe() возвращает no-op функцию отписки вместо ошибки.

Нужна реактивная версия? Смотрите Видимость элемента для Vue или React-хуки для React — оба оборачивают этот же движок и используют тот же пул.