Chrome扩展Content Script获取自定义Custom Elements返回undefined问题
问题根因
Chrome扩展content script运行在**孤立世界(Isolated World)环境,和宿主页面的JS上下文完全隔离,二者仅共享DOM树,各自持有独立的window全局对象副本。
你通过content script动态注入的外部ES模块脚本,实际运行在页面原生JS上下文,所以它注册的pose-viewer自定义元素存储在页面上下文的window.customElements**对象中,content script直接访问自身上下文的window.customElements自然无法读取到对应结果。
你在浏览器控制台手动执行代码能正常拿到结果,是因为控制台默认绑定的是页面上下文,和你观察到的现象完全匹配。
解决方案
有两种常用方案解决上下文隔离带来的访问问题:
方案1:主动获取页面上下文的全局对象
通过DOM属性间接读取页面原生window对象,再访问其下的customElements:
// 获取页面原生window对象 const pageWindow = document.documentElement.ownerDocument.defaultView; const script = document.createElement('script') script.setAttribute('type', 'module'); script.setAttribute('src', 'https://unpkg.com/pose-viewer@0.2.3/dist/pose-viewer/pose-viewer.esm.js'); document.body.appendChild(script); while (!pageWindow.customElements.get('pose-viewer')) { await new Promise(resolve => requestAnimationFrame(resolve)) console.log(pageWindow.customElements.get('pose-viewer')) } console.log('defined')
方案2:将完整逻辑注入到页面上下文执行
如果后续需要操作自定义元素的内部属性、方法,更稳妥的方式是把所有相关逻辑都封装为注入脚本,直接在页面上下文运行:
const runScript = document.createElement('script'); runScript.textContent = ` (async () => { const script = document.createElement('script') script.setAttribute('type', 'module'); script.setAttribute('src', 'https://unpkg.com/pose-viewer@0.2.3/dist/pose-viewer/pose-viewer.esm.js'); document.body.appendChild(script); while (!window.customElements.get('pose-viewer')) { await new Promise(resolve => requestAnimationFrame(resolve)) console.log(window.customElements.get('pose-viewer')) } console.log('defined') // 所有自定义元素相关操作逻辑都放在此处执行 })() `; document.body.appendChild(runScript);
内容的提问来源于stack exchange,提问作者israelk
相关产品推荐
相关产品推荐

