当前位置: 首页 > 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.lryc.cn/news/607351.html

相关文章:

  • cesium FBO(四)自定义相机渲染到Canvas(离屏渲染)
  • 开源工具FossFLOW,绘制技术图表
  • 嵌入式GPU图像渲染工具全景实用指南(i.MX8MP平台)
  • Python深度解析与爬虫进阶:从理论到企业级实践
  • ubuntu 镜像克隆
  • Git 实现原理剖析
  • 【编号394】阿姆河流域土地利用分布数据(1990-2015)
  • 智能问数系统的调研
  • 【工具分享】模拟接口请求响应的Chrome插件ModResponse
  • 什么是doris
  • 第七章 愿景12 小萍分享《人性的弱点》
  • 软件性能优化:善用80-20法则,精准突破瓶颈
  • grafana/lock-stack 日志 Pipeline 配置
  • 前端渲染三国杀:SSR、SPA、SSG
  • npm报错:npm install 出现“npm WARN old lockfile”
  • 工程化(二):为什么你的下一个项目应该使用Monorepo?(pnpm / Lerna实战)
  • R 语言文件读写、批量读取与图片保存实用代码汇总
  • 逻辑回归参数调优实战指南
  • 【Linux系列】Vim 中删除当前单词
  • Master Prompt:AI时代的万能协作引擎
  • 法国彩虹重磅发布EmVue:解锁能源监控新方式
  • 使用 Trea cn 设计 爬虫程序 so esay
  • 【Jetson orin-nx】使用Tensorrt并发推理四个Yolo模型 (python版)
  • Git 各场景使用方法总结
  • JVM、JDK、JRE的区别
  • 如何快速给PDF加书签--保姆级教程
  • vue2实现类似chatgpt和deepseek的AI对话流打字机效果,实现多模型同时对话
  • 在PyCharm中将现有Gitee项目重新上传为全新项目
  • 单变量单步时序预测:CNN-LSTM卷积神经网络结合长短期记忆神经网络
  • 服务器问题调试-线上系统退出时的一般解决思路