You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Chrome扩展content script调用customElements.define报错问题咨询

错误原因

  • 执行时机过早:如果你的content script配置了run_at: document_start,此时页面DOM还未完成初始化,window.customElements接口还未挂载到window对象上,访问时返回null,调用define方法就会抛出该错误。
  • 隔离环境限制:Chrome扩展的content script运行在独立的隔离世界中,部分低版本Chrome不会向隔离世界暴露window.customElements接口,直接访问就会得到null。

解决方案

方案1:调整content script执行时机

修改manifest.json中content script的执行时机配置,将run_at设置为document_idle或document_end,确保页面基础接口初始化完成后再执行代码:

{
  "content_scripts": [
    {
      "matches": ["<all_urls>"],
      "js": ["content.js"],
      "run_at": "document_idle"
    }
  ]
}

方案2:增加接口存在判断

如果需要提前执行代码,可以添加轮询判断,等window.customElements可用后再执行注册逻辑:

function tryRegister() {
  if (!window.customElements) {
    setTimeout(tryRegister, 30);
    return;
  }
  class MyWebComponent extends HTMLElement {
    constructor() {
        super();
        this.attachShadow({ mode: "open" });
    }
    connectedCallback() {
        this.shadowRoot.innerHTML = `
            <p>I'm in the Shadow Root!</p>
        `;
    }
  }
  window.customElements.define("my-web-component", MyWebComponent);
}
tryRegister();

方案3:将注册逻辑注入主世界执行

页面主世界的window.customElements接口是完整可用的,你可以通过创建script标签的方式把自定义元素注册逻辑注入到主世界执行:

const injectScript = document.createElement('script');
injectScript.textContent = `
class MyWebComponent extends HTMLElement {
  constructor() {
      super();
      this.attachShadow({ mode: "open" });
  }
  connectedCallback() {
      this.shadowRoot.innerHTML = \`
          <p>I'm in the Shadow Root!</p>
      \`;
  }
}
window.customElements.define("my-web-component", MyWebComponent);
`;
document.documentElement.appendChild(injectScript);
injectScript.remove();

内容的提问来源于stack exchange,提问作者user17085802

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.01 08:15:01