Отслеживание позиции элемента
createElementTracker(element, options?) — отслеживает позицию элемента относительно viewport (его прямоугольник, насколько он уже прошёл через область видимости и расстояние от центра viewport), обновляется на общем цикле requestAnimationFrame. Передайте root, чтобы считать позицию относительно прокручиваемого контейнера вместо окна — у элемента внутри overflow: auto (панель дашборда, модалка) собственный «viewport», который не совпадает с окном вообще.
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
| Поле | Тип | Примечание |
|---|---|---|
rect | DOMRectLike | Простой снапшот { top, left, right, bottom, width, height } из getBoundingClientRect() — всегда привязан к окну, независимо от root. |
viewportProgress | number | 0..1 — от появления элемента у нижнего края «viewport»-рамки до ухода за верхний край. Рамка — окно по умолчанию, либо прямоугольник root, если он задан. |
distanceFromCenter | number | Смещение в пикселях между вертикальным центром элемента и вертикальным центром рамки (окна или root) — отрицательное, если элемент выше центра. |
Без window (серверный рендеринг) возвращается статичный трекер, чьё состояние всегда { rect: { top: 0, left: 0, right: 0, bottom: 0, width: 0, height: 0 }, viewportProgress: 0, distanceFromCenter: 0 }.
Пример:
import { createElementTracker } from '@macrulez/inview-core'
const tracker = createElementTracker(document.querySelector('#card')!)
tracker.subscribe((state) => {
console.log(`${Math.round(state.viewportProgress * 100)}% через viewport`)
})Отслеживание внутри прокручиваемой панели вместо окна:
const panel = document.querySelector('#dashboard-panel')!
const tracker = createElementTracker(document.querySelector('#widget')!, { root: panel })Нужна реактивная версия или готовый параллакс-эффект? Смотрите Позиция элемента во viewport и Параллакс-слой для Vue, или React-хуки для React.