Javascript的Observer模式扮演者至关重要的角色,Observer模式允许开发者监听对象的变化,并在变化时自动执行相应的操作。这种机制在前端开发中尤为重要,尤其是在处理动态数据、用户交互和异步操作时。
接下来盘点一下Javascript中那些至关重要的Observer
# MutationObserver 监听DOM变化
MutationObserver是Javascript中用于监听DOM树变化的接口。它可以在DOM节点被添加、删除或修改时触发回调函数。与旧的Mutation Events相比,MutationObserver更加高效和灵活
# 使用场景
- 动态加载内容时,监听新元素的插入
- 监听元素属性变化,如class、style等
- 监听子节点的变化,如添加或删除子元素
实例代码
// 获取需要观察的目标元素
const targetNode = document.getElementById('target');
// 配置观察选项:监听属性变化、子节点以及子树的变化
const config = {
attributes: true,
childList: true,
subtree: true
}
// 定义回调函数,当观察到变化时执行
const callback = function(mutationsList, observer) {
// 遍历所有观察到的变化
for(let mutation of mutationsList) {
if(mutation.type === 'childList') {
console.log('子节点发生变化')
} else if(mutation.type === 'attributes'){
console.log('属性发生变化:', mutation.attributeName)
}
}
}
// 创建MutationObserver实例,并传入回调函数
const observer = new MutationObserver(callback);
// 开始观察目标节点,传入配置项
observer.observe(targetNode, config);
// 如果需要停止观察,可以调用disconnect方法
observer.disconnect();
# IntersectionObserver 监听元素可见性
IntersectionObserver用于监听目标元素与其祖先元素或视口的交叉状态。它可以帮助开发者判断元素是否进入或者离开窗口,从而实现懒加载、无限滚动等功能
# 使用场景
- 图片懒加载:当图片进入视口时在加载
- 无限滚动:监听列表底部元素,触发加载更多内容
- 广告曝光统计:统计广告元素的曝光次数
// 获取需要观察的目标元素
const target = document.getElementById('lazy-images');
// 配置观察选项
const options = {
root: null, // 根元素,默认为视口
rootMargin: '0px', // 根元素的外边距
threshold: 0.5 // 交叉比例阈值,当目标元素进入或离开根元素的50%时触发回调
}
// 定义回调函数,当目标元素与视口交叉时执行
const callback = function(entries, observer) {
entries.forEach(entry => {
if(entry.isIntersecting) {
console.log('元素进入视口');
//加载图片(将data-src的值赋给src)
entry.target.src = entry.target.dataset.src;
observer.unobserve(entry.target);
}
})
}
// 创建IntersectionObserver实例,并传入回调函数和配置项
const observer = new IntersectionObserver(callback, options);
// 开始观察目标元素
observer.observe(target);
# ResizeObserver 监听元素尺寸变化
ResizeObserver用于监听元素尺寸变化。与传统的window.resize事件不同,ResizeObserver可以精确监听单个元素的尺寸变化,而不受页面其他部分影响
# 使用场景
- 响应式布局:根据元素尺寸动态调整布局
- 图表重绘:当容器尺寸变化时,重新绘制图表
- 自适应组件:根据父容器尺寸调整子组件大小
// 获取需要观察的目标元素
const target = document.getElementById('resizeable');
// 定义回调函数,当目标元素尺寸变化时执行
const callback = function(entries, observer) {
for(let entry of entries) {
// 获取元素新尺寸
const {
width,
height
} = entry.contentRect;
console.log(`元素新尺寸: ${width}x${height}`);
}
}
// 创建ResizeObserver实例,并传入回调函数
const observer = new ResizeObserver(callback);
// 开始观察目标元素
observer.observe(target);
# PerformanceObserver 监听性能指标
PerformanceObserver 用于监听性能相关的指标,如资源加载时间、首次绘制时间等。它可以帮助开发者分析和优化页面性能
# 使用场景
- 监控页面加载性能
- 分析资源加载时间
- 监控场任务和用户交互延迟
// 定义回调函数,当性能指标变化时执行
const callback = function(list, observer) {
for(let entry of list.getEntries()) {
console.log(`性能指标: ${entry.name}, 耗时: ${entry.duration}`);
}
}
// 创建PerformanceObserver实例,并传入回调函数
const observer = new PerformanceObserver(callback);
// 开始观察性能指标
observer.observe({
entryTypes: ['resource', 'paint', 'longtask']
});
// 停止观察性能指标
observer.disconnect();