提供了一套异步检测目标元素与祖先元素或 viewport 相交情况变化的方法。如果不兼容,需要使用 Element.getBoundingClientRect() 方法去获取相对位置,外加 scroll 事件监听去实现对应的功能。
注册的回调函数将会在主线程中被执行,回调任务将在浏览器空闲的时候被增加在任务队列中等待执行, 如果耗时操作会使得当前任务占用时间过长,造成卡顿。所以该函数执行速度要尽可能的快。如果有一些耗时的操作需要执行,建议使用 Window.requestIdleCallback() 方法。
<body>
<div style="height: 300px;background-color: #f7f7f7;" class="div-1">1</div>
<div style="height: 300px;" class="div-2">2</div>
<div style="height: 300px;" class="div-3">3</div>
<div style="height: 300px;background-color: #f7f7f7;" class="div-4">4</div>
</body>
<script>
function intersectionExecFunc(infos, intersectionOpts) {
infos.forEach(info => {
/**
* Each info describes an intersection change for one observed target element:
* info 描述每一个被观察元素的交叉信息的改变
*/
/** 绑定元素矩形区域信息, 包括 x, y, width, height, top, left, right, bottom */
console.log('boundingClientRect', info.boundingClientRect);
/** 交叉比例, 也可以理解为与父级的交叉部分比例 */
console.log('intersectionRatio', info.intersectionRatio);
/** 交叉部分区域信息 */
console.log('intersectionRect', info.intersectionRect);
/** 是否满足 threshold 设定的交叉比例 */
console.log('isIntersecting', info.isIntersecting);
/** 对应的设置的父元素的矩形区域信息 */
console.log('rootBounds', info.rootBounds);
// console.log(info.target);
/** 交叉的时间, 对比时间为实例化的时间 */
console.log('time', info.time);
console.log('~~~~~~~~~~~~');
});
};
const intersectionOption = {
// root: document.querySelector('.div-4'),
/** 触发方法的临界值, 当达到这个交叉比例时触发, 如果是一个数组, 那么在对应的临界点便触发, 取值在 0.0 和 1.0 之间 */
threshold: 0.5,
};
const intersection = new IntersectionObserver(intersectionExecFunc, intersectionOption);
/** 创建的交叉观察对象可观察多个是否可见的元素 */
intersection.observe(document.querySelector('.div-3'));
intersection.observe(document.querySelector('.div-4'));
/** 可解除对应元素的观察 */
// intersection.unobserve(document.querySelector('.div-3'));
/** 停止所有的观察 */
// intersection.disconnect();
</script>
如上所示,创建的观察实例可以观察多个元素。
如下简要使用示例, 实际使用中, 如果监听了某个元素的变动, 一定要调用 unobserve 取消某个元素的监听 或者 调用 disconnect() 取消所有元素的监听, 以免造成性能问题
const resizeObserver = new ResizeObserver((entries, resizeOb) => {
/* 如果监听多个这里就是多项 **/
for (const entry of entries) {
console.log(entry);
/* Firefox 实现的 contentBoxSize 是一个单项值, 并非数组 **/
const contentBoxSize = Array.isArray(entry.contentBoxSize)
? entry.contentBoxSize[0]
: entry.contentBoxSize;
console.log(contentBoxSize);
}
/* 在内部也能直接取到实例, 对其进行操作, 比如取消监听 **/
console.log('对应的实例 =>', resizeOb);
});
/* 假设页面中有某个元素 **/
const divEl = document.querySelector('.container');
/* 监听页面中某个元素 **/
resizeObserver.observe(divEl);
/* 取消某个监听 **/
// resizeObserver.unobserve(divEl);
/* 取消全部监听 **/
// resizeObserver.disconnect();
observe 方法支持两个参数:
observe(target, options);
该种监听方式产生的应该是一个宏任务, 具体。通过 performance录制任务执行过程。
该接口可以监控 DOM 树所做的修改,是旧的 Mutation Events 功能的替代品,该功能是 DOM3 Events 规范的一部分。
如下, 监听页面中某个元素, 定义一个按钮点击修改内容和属性, 可以看到打印两个结果, 知道具体修改了哪些内容, 如果不使用了一定要调用 disconnect 方法取消监听。
/* 假设页面中有该元素 **/
const el = document.querySelector('.container');
function mutationObFunc(mutations, paramOb) {
/*
* 每一项都是检测到的变动项结果, 可获取相关参数
* 如果修改多个或者监听多个不同的修改, 就会产生多项
*/
for (const mutation of mutations) {
console.log(mutation);
}
/* 通过该实例可以取消监听, 做些操作 **/
console.log('实例对象 =>', paramOb);
}
const mutationOb = new MutationObserver(mutationObFunc);
const observerOptions = {
/* 观察目标子节点的变化,是否有添加或者删除 **/
childList: true,
/* 观察属性变动 **/
attributes: true,
/* 观察后代节点,默认为 false **/
subtree: true,
};
mutationOb.observe(el, observerOptions);
/* 如果不需要了, 停止观察 **/
// mutationOb.disconnect();
/* 点击按钮修改属性和内容 **/
const btn = document.querySelector('.btn');
btn.addEventListener('click', () => {
el.innerText = 'q w e r t y';
el.style.width = '100px';
});
该方式产生的任务应该是一个微任务, 具体, 通过performance可录制执行过程。
参考文档:
因篇幅问题不能全部显示,请点此查看更多更全内容
Copyright © 2019- awee.cn 版权所有 湘ICP备2023022495号-5
违法及侵权请联系:TEL:199 1889 7713 E-MAIL:2724546146@qq.com
本站由北京市万商天勤律师事务所王兴未律师提供法律服务