当前位置: 首页 > news >正文

浏览器【详解】内置Observer(共五种,用于前端监控、图片懒加载、无限滚动、响应式布局、生成安全报告等)

通用语法

浏览器的内置Observer都需要通过 new 来创建实例 ob (自定义名称)

  • 开始/继续监听 ob.observe(targetNode, config)
    • targetNode 目标元素
    • config 配置
  • 暂停监听 ob.disconnect()
  • 停止监听 ob.unobserve(targetNode)

MutationObserver

监听DOM 元素的变化(如节点增删、属性修改、文本内容变化等)

可用于延迟批量处理变化(避免频繁触发回调),提升性能。

// 选择目标节点
const targetNode = document.getElementById('target');// 配置观察选项
const config = {attributes: true, // 监听属性变化childList: true, // 监听子节点增删subtree: true // 监听所有后代节点
};// 回调函数:变化发生时执行
const callback = (mutationsList) => {for (const mutation of mutationsList) {if (mutation.type === 'childList') {console.log('子节点发生变化');} else if (mutation.type === 'attributes') {console.log(`属性 ${mutation.attributeName} 发生变化`);}}
};// 创建观察者实例
const observer = new MutationObserver(callback);// 开始观察目标节点
observer.observe(targetNode, config);// 停止观察(必要时)
// observer.disconnect();

交叉观察器 IntersectionObserver

监测目标元素与视口或祖先元素的交叉状态(如元素进入 / 离开视口),常用于懒加载、滚动动画等场景。

  • 高效检测元素可见性,避免频繁触发scroll事件导致的性能问题。
  • 支持配置交叉区域的阈值(如元素可见 50% 时触发)。
// 创建观察器
let ob = new IntersectionObserver(callback, option);
  • 在元素进入视口和离开视口时,都会触发回调函数 callback
  • callback 的参数是由 相交观察器条目 构成的数组,数组的数量由被观察对象的数量决定。

观察多个对象

ob.observe(elementA);
ob.observe(elementB);

相交观察器条目

共六个属性

  • time:可见性发生变化的时间,是一个高精度时间戳,单位为毫秒
  • target:被观察的目标元素,是一个 DOM 节点对象
  • rootBounds:根元素的矩形区域的信息,getBoundingClientRect()方法的返回值,如果没有根元素(即直接相对于视口滚动),则返回null
  • boundingClientRect:目标元素的矩形区域的信息
  • intersectionRect:目标元素与视口(或根元素)的交叉区域的信息
  • intersectionRatio:目标元素的可见比例,即intersectionRect占boundingClientRect的比例,完全可见时为1,完全不可见时小于等于0

配置选项

  • threshold 触发的阈值,默认值为 [0] ,即元素一出现即触发
  threshold: 0.1 // 元素可见10%时触发
  threshold: [0.5,1] // 元素可见50% 和 100% 时都触发
  • root 指定目标元素所在的容器节点(即根元素),容器元素必须是目标元素的祖先节点。
  • rootMargin 定义根元素的margin,用来扩展或缩小rootBounds这个矩形的大小,从而影响intersectionRect交叉区域的大小。它使用CSS的定义方法,比如10px 20px 30px 40px,表示 top、right、bottom 和 left 四个方向的值。

注意事项

  • IntersectionObserver 是异步的,不随着目标元素的滚动同步触发。
  • IntersectionObserver 的优先级非常低,只在其他任务执行完,浏览器有了空闲才会执行。

实战范例 – 图片懒加载

// 目标元素(如图片)
const target = document.querySelector('.lazy-image');// 配置选项
const options = {root: null, // 以视口为参考rootMargin: '0px', // 扩展/收缩参考区域threshold: 0.1 // 元素可见10%时触发
};// 回调函数:交叉状态变化时执行
const callback = (entries) => {entries.forEach(entry => {if (entry.isIntersecting) {// 元素进入视口,加载图片entry.target.src = entry.target.dataset.src;// 停止观察已加载的元素observer.unobserve(entry.target);}});
};// 创建观察者实例
const observer = new IntersectionObserver(callback, options);// 开始观察目标元素
observer.observe(target);

function query(selector) {return Array.from(document.querySelectorAll(selector));
}var observer = new IntersectionObserver(function(changes) {changes.forEach(function(change) {var container = change.target;var content = container.querySelector('template').content;container.appendChild(content);observer.unobserve(container);});}
);query('.lazy-loaded').forEach(function (item) {observer.observe(item);
});

实战范例 – 无限滚动

var intersectionObserver = new IntersectionObserver(function (entries) {// 如果不可见,就返回if (entries[0].intersectionRatio <= 0) return;loadItems(10);console.log('Loaded new items');});// 开始观察
intersectionObserver.observe(document.querySelector('.scrollerFooter')
);

无限滚动时,最好在页面底部有一个页尾栏(又称sentinels)。一旦页尾栏可见,就表示用户到达了页面底部,从而加载新的条目放在页尾栏前面。这样做的好处是,不需要再一次调用observe()方法,现有的IntersectionObserver可以保持使用。

ResizeObserver

监听元素尺寸变化(如宽度、高度改变),适用于响应式布局、动态调整 UI 等场景。

// 目标元素
const target = document.querySelector('.resizable-box');// 回调函数:尺寸变化时执行
const callback = (entries) => {for (const entry of entries) {const { width, height } = entry.contentRect;console.log(`元素尺寸变化:${width}px × ${height}px`);}
};// 创建观察者实例
const observer = new ResizeObserver(callback);// 开始观察目标元素
observer.observe(target);// 停止观察(必要时)
// observer.unobserve(target);

PerformanceObserver

监测性能指标数据(如页面加载时间、资源加载性能、长任务等),帮助开发者分析和优化网页性能。

  • 捕获各种性能相关事件(如 navigation、resource、longtask 等)。
  • 异步获取性能数据,不阻塞主线程。
// 监测长任务(阻塞主线程超过50ms的任务)
const observer = new PerformanceObserver((list) => {list.getEntries().forEach(entry => {console.log(`长任务持续时间:${entry.duration}ms`);});
});// 开始观察长任务
observer.observe({ type: 'longtask', buffered: true });

ReportingObserver

收集浏览器生成的各种报告(如 CSP 违规、废弃 API 使用警告、干预报告等),帮助开发者监控应用在生产环境中的问题。

  • 捕获浏览器的安全、性能或兼容性相关报告。
  • 支持批量处理和缓冲已发生的报告。
// 监测废弃API使用和干预报告
const observer = new ReportingObserver((reports) => {reports.forEach(report => {console.log(`报告类型:${report.type},内容:`, report.body);});
}, { types: ['deprecation', 'intervention'], buffered: true });// 开始观察报告
observer.observe();
http://www.dtcms.com/a/309261.html

相关文章:

  • 算法26. 删除有序数组中的重复项
  • 宝塔网站如何禁止使用IP访问
  • Shell脚本批量检测IP的443端口联通性
  • ai项目多智能体
  • 【从0开始学习Java | 第11篇】String、StringBuilder与StringBuffer
  • 微信小程序转Vue2组件智能提示词
  • 隧道安全监测哪种方式好?精选方案与自动化监测来对比!
  • 11.Layout-Pinia优化重复请求
  • C++赋值运算符重载
  • PHP Zip 文件操作详解
  • 汽车供应链PPAP自动化审核指南:如何用AI实现规则精准匹配与文件智能校验
  • MyBatis核心
  • MySQL——视图
  • C++对象访问有访问权限是不是在ide里有效
  • StarRocks vs. Trino
  • JavaWeb(苍穹外卖)--学习笔记16(定时任务工具Spring Task,Cron表达式)
  • RAGFLOW~Enable RAPTOR
  • 【云计算】云主机的亲和性策略(二):集群节点组
  • [ java 网络 ] TPC与UDP协议
  • 微波(Microwave)与毫米波(Millimeter wave)简介
  • 动态域名解析(DDNS)到底有什么用?
  • OSPF综合大实验
  • 下次接好运~
  • Oracle EBS 缺少adcfgclone.pl文件
  • 一分钟了解IO-Link 系列集线器
  • LaTeX 复杂图形绘制教程:从基础到进阶
  • Deep Height Decoupling for Precise Vision-based 3D Occupancy Prediction
  • 数据结构前篇 - 深入解析数据结构之复杂度
  • Leetcode——53. 最大子数组和
  • 如何将消息转移到新 iPhone