前言
本文使用React Hooks 构建一个监听DOM元素曝光的Custom Hooks,主要功能是监听DOM元素是否在规定内曝光,从而可以完成曝光打点。
过去我们监听DOM元素都是通过监听scroll事件来监听目标元素是否在可视区,这样我们需要获取目标元素的一些数据。这样似乎很麻烦,而通过 Intersection Observer 来完成监听,更加方便、友好。
Intersection Observer
MDN: IntersectionObserver接口 (从属于Intersection Observer API) 提供了一种异步观察目标元素与其祖先元素或顶级文档视窗(viewport)交叉状态的方法。祖先元素与视窗(viewport)被称为根(root)。
其他相关概念可见 谈谈IntersectionObserver懒加载 、 IntersectionObserver API 使用教程
简单来说这个对象会观察目标元素,当目标元素与它的祖先元素或者可视区发生交叉时,会触发回调函数。
通过这个对象我们可以监听需要曝光打点的元素,更方便的实现打点。同时我们不需要监听scroll事件以及相对应的DOM操作,减少了性能的开销。
Intersection Observer 在 React 中的实践
为了能够在不同的场景中使用,我们可以将其封装成HOOKS,更方便的调用该方法
1. 定义 useIntersectionObserver 函数
// useIntersectionObserver.ts
// 定义参数函数类型以及返回值类型
import { useState, useCallback, useEffect } from 'react'
type NumberList = number[]
type ObserverList = Array<React.RefObject<any>>
type CallbackFunction = (indexList: NumberList) => void
type ResultType = [React.Dispatch<React.SetStateAction<React.RefObject<any>[]>>]
function UseIntersectionObserver (
observerList: ObserverList,
callback: CallbackFunction,
infinite: boolean = false,
opt: IntersectionObserverInit = {}
): ResultType {
// list 为需要监听的元素列表。setList做为UseIntersectionObserver函数的返回值,可以让调用者修改需要监听的 list
const [list, setList] = useState<ObserverList>(observerList)
// intersectionObserver: 观察者对象
let intersectionObserver: IntersectionObserver | null = null
// ...
return [setList]
}
const useIntersectionObserver = UseIntersectionObserver
export default useIntersectionObserver
复制代码<