如何在频繁重运行的JS拦截器中实现代码仅执行一次,避免重复初始化Mutation Observer
解决方案
核心思路是将执行状态标记挂载到全局window对象上,全局对象在页面完整生命周期内仅存在一份,不会随代码重复执行被重置,以此保证逻辑仅运行一次。
实现代码
你可以直接把以下代码放到你的注入位置,无论该位置代码被重复执行多少次,Observer都只会初始化一次:
// 自定义全局标记,命名尽量特殊避免和页面其他变量冲突 const GLOBAL_FLAG = '__SWAGGER_MUTATION_OBSERVER_INITED'; if (!window[GLOBAL_FLAG]) { // 标记为已执行,后续代码重复运行都会跳过该分支 window[GLOBAL_FLAG] = true; // 此处写你需要单次执行的所有逻辑,例如初始化Mutation Observer const observer = new MutationObserver((mutationList) => { // 你的Observer业务逻辑 console.log('监听到DOM变化', mutationList); }); // 启动监听,根据你的需求调整监听配置 observer.observe(document.body, { childList: true, subtree: true, attributes: true }); // 可选:把Observer实例挂载到全局,后续需要停止监听时可以直接调用 window.__SWAGGER_MUTATION_OBSERVER = observer; }
原理解释
你之前的方案使用闭包存储执行标记,每次代码重新执行时都会创建全新的闭包作用域,不同闭包内的标记互不影响,所以会出现多次执行的问题。而本方案使用全局window对象存储标记,全局对象是页面唯一的,只要被赋值后就不会再回到初始的undefined状态,因此可以保证逻辑仅执行一次。
注意事项
- 全局标记的命名尽量特殊(比如加上专属前缀、下划线等),避免和页面其他脚本的全局变量重名,导致判断逻辑出错。
- 如果你的脚本是在多个不同页面生效,每个页面的全局对象是独立的,会在每个页面各初始化一次,符合正常业务预期。
内容的提问来源于stack exchange,提问作者Vaccano
相关产品推荐
相关产品推荐

