Проверить, виден ли элемент на экране пользователя, очень просто с помощью API Intersection Observer. Этот API поддерживается всеми основными браузерами.
API Intersection Observer позволяет нам обнаруживать пересечения элемента с другим элементом. В нашем случае мы будем наблюдать за пересечениями между элементом React и областью просмотра браузера.
Для этого мы создадим пользовательский хук, чтобы повторно использовать этот код там, где он нам нужен.
В нашем пользовательском хуке мы будем использовать useState
для хранения статуса пересечения элемента.
export function useIsVisible() {
const [isIntersecting, setIntersecting] = useState(false);
return isIntersecting;
}
Хуку нужна ссылка на элемент React, который мы хотим наблюдать. Мы будем использовать реквизит ref
для передачи элемента хуку.
export function useIsVisible(ref) {
const [isIntersecting, setIntersecting] = useState(false);
return isIntersecting;
}
Наконец, нам нужно создать экземпляр IntersectionObserver
и наблюдать за элементом. Конструктор IntersectionObserver
принимает в качестве первого аргумента функцию обратного вызова, которая вызывается, когда элемент пересекается с областью просмотра.
Для этого мы будем использовать хук useEffect
, чтобы избежать создания новых наблюдателей при повторном рендеринге.
export function useIsVisible(ref) {
const [isIntersecting, setIntersecting] = useState(false);
useEffect(() => {
const observer = new IntersectionObserver(([entry]) =>
setIntersecting(entry.isIntersecting)
);
observer.observe(ref.current);
}, [ref]);
return isIntersecting;
}
Для повышения производительности мы будем вызывать IntersectionObserver.disconnect(), чтобы прекратить наблюдение за изменениями, когда компонент размонтирован или в хук передан новый элемент.
export function useIsVisible(ref) {
const [isIntersecting, setIntersecting] = useState(false);
useEffect(() => {
const observer = new IntersectionObserver(([entry]) =>
setIntersecting(entry.isIntersecting)
);
observer.observe(ref.current);
return () => {
observer.disconnect();
};
}, [ref]);
return isIntersecting;
}
Наш хук готов к использованию. Для его использования нам нужно только вызвать его из компонента React и передать ссылку на элемент, который мы хотим проверить, виден он или нет.
export function MyComponent() {
const ref = useRef();
const isVisible = useIsVisible(ref);
return (
<div ref={ref}>
<p>{isVisible ? "Visible" : "Not visible"}</p>
</div>
);
}
Вы можете увидеть реальный пример использования этого хука на моем сайте. Я использую хук для определения того, что пользователь прокручивает страницу до самого низа, а затем загружает комментарии к записи в блоге. Вы можете посмотреть исходный код компонента здесь. Введите любой из постов блога и прокрутите страницу к низу, чтобы увидеть его в действии.
Ссылки
- API Intersection Observer
- IntersectionObserver.disconnect()