Skip to content

Отслеживание позиции элемента ​

createElementTracker(element, options?) — отслеживает позицию элемента относительно viewport (его прямоугольник, насколько он уже прошёл через область видимости и расстояние от центра viewport), обновляется на общем цикле requestAnimationFrame. Передайте root, чтобы считать позицию относительно прокручиваемого контейнера вместо окна — у элемента внутри overflow: auto (панель дашборда, модалка) собственный «viewport», который не совпадает с окном вообще.

ts
function createElementTracker(element: HTMLElement, options?: ElementTrackerOptions): ElementTracker

interface ElementTrackerOptions {
  root?: Element | null // по умолчанию null (окно)
}

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

getState() ​

() => ElementTrackerState

Синхронно читает текущее состояние, без подписки.

subscribe(callback) ​

(callback: (state: ElementTrackerState) => void) => () => void

Сразу вызывает callback с текущим состоянием, затем — только когда состояние реально изменилось (поверхностное сравнение полей — без уведомления на тике rAF, где ничего не сдвинулось). Возвращает функцию отписки.

destroy() ​

() => void

ElementTrackerState ​

ПолеТипПримечание
rectDOMRectLikeПростой снапшот { top, left, right, bottom, width, height } из getBoundingClientRect() — всегда привязан к окну, независимо от root.
viewportProgressnumber0..1 — от появления элемента у нижнего края «viewport»-рамки до ухода за верхний край. Рамка — окно по умолчанию, либо прямоугольник root, если он задан.
distanceFromCenternumberСмещение в пикселях между вертикальным центром элемента и вертикальным центром рамки (окна или root) — отрицательное, если элемент выше центра.

Без window (серверный рендеринг) возвращается статичный трекер, чьё состояние всегда { rect: { top: 0, left: 0, right: 0, bottom: 0, width: 0, height: 0 }, viewportProgress: 0, distanceFromCenter: 0 }.

Пример:

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

const tracker = createElementTracker(document.querySelector('#card')!)

tracker.subscribe((state) => {
  console.log(`${Math.round(state.viewportProgress * 100)}% через viewport`)
})

Отслеживание внутри прокручиваемой панели вместо окна:

ts
const panel = document.querySelector('#dashboard-panel')!
const tracker = createElementTracker(document.querySelector('#widget')!, { root: panel })

Нужна реактивная версия или готовый параллакс-эффект? Смотрите Позиция элемента во viewport и Параллакс-слой для Vue, или React-хуки для React.