ResizeObserver 监听尺寸
什么是 ResizeObserver
ResizeObserver 用于监听 DOM 元素节点增减、属性/宽高/内容的变化。相较于 window.onresize 只能获取/设置当前窗口的 resize 事件更为高效灵活。
一、基本用法
ResizeObserver 是个构造函数。需要使用 new 关键字调用,通过 observe 方法指定监听的元素。
1、通用监听
const resizeObserver = new ResizeObserver(entries => {
console.log(entries)
});
// 监听单个 DOM 元素尺寸的变化
resizeObserver.observe(document.querySelector('#box'))
当该 DOM 元素尺寸变化时输出:
可通过监听 body 节点来模拟 window.onresize
:
const resizeObserver = new ResizeObserver(entries => {
console.log(entries)
});
// 监听整个 body 的变化
resizeObserver.observe(document.body)
当窗口尺寸发生变化时输出:
2、只监听某一类变化
observe 的第二个参数是可选值,可指定只监听某一类变化,其中,必须有 childList
、attributes
和 characterData
中一种或多种,否则会报错。可设置的属性如下:
childList
(布尔值),表示是否监听子节点的变动;attributes
(布尔值),表示是否监属性的变动;characterData
(布尔值),表示是否监听节点内容/文本的变动;subtree
(布尔值),表示是否监听所有后代节点;attributeFilter
(数组),表示观察特定属性;attributeOldValue
(布尔值),表示观察 attributes 变动时,是否需要记录变动前的属性值;characterDataOldValue
(布尔值),表示观察 characterData 变动,是否需要记录变动前的值;
const resizeObserver = new ResizeObserver(entries => {
console.log(entries)
});
const options = {
childList: true, // 子节点的变动(新增、删除或者更改)
attributes: true, // 属性的变动
characterData: true, // 节点内容或节点文本的变动
subtree: true, // 是否将观察器应用于该节点的所有后代节点
attributeFilter: ['class', 'style'], // 观察特定属性
attributeOldValue: true, // 观察 attributes 变动时,是否需要记录变动前的属性值
characterDataOldValue: true // 观察 characterData 变动,是否需要记录变动前的值
}
resizeObserver.observe(document.querySelector('#box'), options)
二、取消监听
与 removeEventListener
同理,需要取消监听。
1、取消单个 resizeObserver 监听
可通过 unobserve 取消指定节点的 resizeObserver 监听。
const resizeObserver = new ResizeObserver(entries => {
console.log(entries)
});
resizeObserver.observe(document.querySelector('#box'))
// 2s 后取消指定节点的监听
setTimeout(() => {
resizeObserver.unobserve(document.querySelector('#box'))
}, 2000)
2、取消所有 resizeObserver 监听
可通过 disconnect 取消所有节点的 resizeObserver 监听。
const resizeObserver = new ResizeObserver(entries => {
console.log(entries)
});
resizeObserver.observe(document.querySelector('#box'))
resizeObserver.observe(document.body)
// 2s 后取消所有节点的监听
setTimeout(() => {
resizeObserver.disconnect()
}, 2000)
在 React 中使用时,一般会在 useEffect 的返回值中对 ResizeObserver 统一销毁:
useEffect(() => {
const resizeObserver = new ResizeObserver(entries => {
console.log(entries)
});
resizeObserver.observe((triggerNode.current as any))
return () => resizeObserver.disconnect()
}, [])