useIntersectionObserver
使用 Intersection Observer API 跟踪元素
useIntersectionObserver 将原生 Intersection Observer API 封装在 React 友好的接口中。它观察目标元素,并在元素与根容器的交叉状态改变时触发带有完整 IntersectionObserverEntry 数组的回调。该 hook 返回一个 stop 函数用于提前断开观察器。
使用场景
- 通过检测哨兵元素进入视口来实现无限滚动
- 仅在图片或重量级组件变得可见时才进行懒加载
- 在特定交叉阈值触发基于滚动的动画或分析事件
注意事项
- 可配置:支持所有标准
IntersectionObserverInit选项(root、rootMargin、threshold),精确控制回调触发时机。 - 清理:观察器在卸载时自动断开。如需手动断开,调用返回的
stop函数。 - 参见
useElementVisibility了解此 hook 的简化布尔值封装。
Usage
Live Editor
function Demo() { const Spacer = () => ( <div style={{ width: "200px", height: "300px", }} /> ); const options = { root: null, rootMargin: "0px", threshold: 1, }; const intersectionRef = useRef(null); const [entry, setEntry] = useState<IntersectionObserverEntry[]>([]); const stop = useIntersectionObserver( intersectionRef, (entry) => { setEntry(entry); }, options ); return ( <div style={{ width: "400px", height: "400px", overflow: "scroll", }} > 滚动我 <Spacer /> <button onClick={() => { stop(); }} > 停止观察 </button> <div ref={intersectionRef} style={{ width: "100px", height: "100px", padding: "20px", background: "var(--c-hj-b)", }} > {entry[0] && entry[0].intersectionRatio < 1 ? "被遮挡" : "完全可见"} </div> <Spacer /> </div> ); }
Result
API
useIntersectionObserver
Returns
() => void: 停止监听函数
Arguments
| 参数名 | 描述 | 类型 | 默认值 |
|---|---|---|---|
| target | dom元素 | BasicTarget<Element> (必填) | - |
| callback | 回调 | IntersectionObserverCallback (必填) | - |
| options | 传递给 IntersectionObserver 的参数 | IntersectionObserverInit | undefined | - |
BasicTarget
export type BasicTarget<T extends TargetType = Element> = (() => TargetValue<T>) | TargetValue<T> | MutableRefObject<TargetValue<T>>;
TargetValue
type TargetValue<T> = T | undefined | null;
TargetType
type TargetType = HTMLElement | Element | Window | Document | EventTarget;