今天开发遇到一个问题,有一个盒子A是一个可拖拽边框调整其大小的盒子,里面有一个滚动加载。当我们高度小的时候会出现滚动条,可是当高度大于内容时就不会出现滚动条也就不会触发滚动加载。于是乎我们需要监听盒子的变化根据盒子高度去加载后面的内容。于是我找到了这个好用的API。
ResizeObserver 接口监视 Element 内容盒或边框盒或者 SVGElement 边界尺寸的变化。
ResizeObserver 避免了通过回调函数调整大小时,通常创建的无限回调循环和循环依赖项。它只能通过在后续的帧中处理 DOM 中更深层次的元素来做到这一点。如果它的实现遵循规范,则应在绘制前和布局后调用 resize 事件。
使用示例
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
</head>
<body>
<div id="box1" style="width: 100px; height: 50px; background-color: red"></div>
<div id="box2" style="width: 100px; height: 50px; background-color: orange"></div>
<button id="btn">变高</button>
<script>
btn.onclick = () => (box1.style.height = parseInt(box1.style.height) + 10 + 'px');
// 创建一个监听器
const observer = new ResizeObserver(enties => {
// enties是我们监听且发生大小改变的盒子列表
for (const item of enties) {
console.log(item);
}
});
// 对指定盒子进行监听--监听的时候会调用我们创建的方法
observer.observe(box1);
observer.observe(box2);
// 取消对某个盒子的监听
// observer.unobserve(box2);
// 取消所有盒子的监听
// observer.disconnect();
</script>
</body>
</html>
我们定义了两个盒子,和一个按钮,给按钮绑定了一个点击事件让第一个盒子变高10个像素,让后我们创建了一个监听器,对两个盒子都进行了监听,监听时会调用我们的创建实例时的方法,当我们点击按钮时盒子1大小改变盒子二没有,于是盒子1调用了我们自己定义的方法。这样当我们页面内部的盒子大小发生改变时我们就能够监听到去做自己的处理逻辑了。
实例传递的方法参数
示例中enties是ResizeObserverEntry类型的数组,他会给到你以下信息:
1、ResizeObserverEntry.borderBoxSize
一个对象,当运行回调时,该对象包含着正在观察元素的新边框盒的大小。
2、ResizeObserverEntry.contentBoxSize
一个对象,当运行回调时,该对象包含着正在观察元素的新内容盒的大小。
3、ResizeObserverEntry.devicePixelContentBoxSize
一个对象,当运行回调时,该对象包含着正在观察元素的新内容盒的大小(以设备像素为单位)。
4、ResizeObserverEntry.contentRect
一个对象,当运行回调时,该对象包含着正在观察元素新大小的 DOMRectReadOnly 对象。请注意,这比以上两个属性有着更好的支持,但是它是 Resize Observer API 早期实现遗留下来的,出于对浏览器的兼容性原因,仍然被保留在规范中,并且在未来的版本中可能被弃用。
5、ResizeObserverEntry.target
对正在观察 Element 或 SVGElement 的引用。
备注
内容盒是放置内容的盒子,即边框盒减去内边距和边框宽度。边框盒包含内容、内边距和边框。更多解释参见盒模型。