在 React.js 中检查元素是否在视口中
Check if an Element is in the Viewport in React.js
在 React.js 中检查元素是否在视口中:
ref
在元素上设置道具。- 使用
IntersectionObserver
API 跟踪元素是否相交。
应用程序.js
import {useEffect, useRef, useState, useMemo} from 'react'; export default function App() { const ref1 = useRef(null); const ref2 = useRef(null); const isInViewport1 = useIsInViewport(ref1); console.log('isInViewport1: ', isInViewport1); const isInViewport2 = useIsInViewport(ref2); console.log('isInViewport2: ', isInViewport2); return ( <div> <div ref={ref1}>Top div {isInViewport1 && '| in viewport ✅'}</div> <div style={{height: '155rem'}} /> <div ref={ref2}>Bottom div {isInViewport2 && '| in viewport ✅'}</div> </div> ); } function useIsInViewport(ref) { const [isIntersecting, setIsIntersecting] = useState(false); const observer = useMemo( () => new IntersectionObserver(([entry]) => setIsIntersecting(entry.isIntersecting), ), [], ); useEffect(() => { observer.observe(ref.current); return () => { observer.disconnect(); }; }, [ref, observer]); return isIntersecting; }
该示例显示了如何检查元素是否在视口中。
IntersectionObserver API使
我们能够检查给定元素是否与文档相交。
该
useIsInViewport
钩子采用指向我们要跟踪的元素的 ref 对象。IntersectionObserver构造函数采用一个函数,该
函数使用一组条目进行调用。
条目是所有观察者的目标元素的数组,这些元素变得比其中一个交叉点观察者比率更可见或更不可见。
每个条目都描述了给定元素与根元素(文档)相交的程度。
我们解构了条目,因为我们的 IntersectionObserver 只跟踪单个元素(我们设置 的元素
ref
)。我们调用了observe()
将我们要跟踪的元素传递给它的方法 –
observer.observe(ref.current)
。
每次元素进入视口或存在视口时,我们传递给IntersectionObserver()
构造函数的函数都会被调用,我们会更新状态。
应用程序.js
// 👇️ gets called every time element enters or leaves viewport new IntersectionObserver(([entry]) => setIsIntersecting(entry.isIntersecting), )
ref
如果我们设置对象
的元素在视口中,useIsInViewport
钩子将返回true
。
如果该元素不在视口中,则挂钩返回false
。
请注意,在初始渲染时,useIsInViewport
钩子将返回 false,因为这是我们传递给useState
–
的初始值const [isIntersecting, setIsIntersecting] = useState(false);
。
如果要跟踪挂钩返回值的更改,请使用
useEffect
挂钩并将该值添加到挂钩的依赖项中。
应用程序.js
const isInViewport1 = useIsInViewport(ref1); console.log('isInViewport1: ', isInViewport1); useEffect(() => { // 👇️ listen for changes console.log(isInViewport1); }, [isInViewport1]);