等待元素存在的代码报错:MutationObserver observe参数非Node类型问题
解决等待元素存在时的MutationObserver错误
你的推测完全正确——错误是因为代码执行时document.body还未被创建,导致调用observe时传入了null,不符合参数必须为Node类型的要求。这种情况常见于content script在document_start时机注入的场景,此时DOM还未完成初始化。
修改后的代码方案
下面是修复后的waitForElm函数,先确保document.body存在后再初始化MutationObserver:
function waitForElm(selector) { return new Promise(resolve => { // 封装元素检查逻辑 const checkTargetElement = () => { const element = document.querySelector(selector); if (element) { resolve(element); return true; } return false; }; // 先检查目标元素是否已存在 if (checkTargetElement()) return; // 初始化Observer的逻辑 const initObserver = () => { const observer = new MutationObserver(() => { if (checkTargetElement()) { observer.disconnect(); } }); observer.observe(document.body, { childList: true, subtree: true }); }; // 处理document.body未加载的情况 if (document.body) { initObserver(); } else { // 监听DOM初始化完成事件 document.addEventListener('DOMContentLoaded', initObserver); // 兜底轮询,防止DOMContentLoaded事件未触发的极端情况 setTimeout(() => { if (document.body) initObserver(); }, 100); } }); } // 使用示例 waitForElm('.some-class').then((elm) => { console.log('Element is ready'); console.log(elm.textContent); });
关键修复点
- 先检查目标元素:避免不必要的Observer初始化
- 等待document.body生成:通过
DOMContentLoaded事件+兜底轮询的方式,确保调用observe时document.body已存在 - 封装重复逻辑:将元素检查逻辑抽离,减少代码冗余
另一种简化方案
如果不需要兜底轮询,也可以直接依赖DOMContentLoaded事件确保DOM初始化完成:
function waitForElm(selector) { return new Promise(resolve => { const checkElement = () => { const elm = document.querySelector(selector); if (elm) resolve(elm); }; // 若DOM已加载完成,直接检查 if (document.readyState !== 'loading') { checkElement(); } // 监听DOM加载完成事件 document.addEventListener('DOMContentLoaded', () => { checkElement(); // 初始化Observer监听后续元素变化 const observer = new MutationObserver(() => { const elm = document.querySelector(selector); if (elm) { resolve(elm); observer.disconnect(); } }); observer.observe(document.body, { childList: true, subtree: true }); }); }); }
内容的提问来源于stack exchange,提问作者senops
相关产品推荐
相关产品推荐

