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

Chrome扩展Manifest V3:重复注入内容脚本致事件监听重复问题修复

修复Chrome扩展Manifest V3中内容脚本重复添加事件监听的问题

问题根源

你当前的判断逻辑typeof iframe === 'undefined'无效,核心原因是每个通过chrome.scripting.executeScript注入的内容脚本都运行在独立的隔离世界(Isolated World)中——不同注入的脚本拥有各自独立的全局作用域,全局变量无法跨脚本共享,所以每次注入时iframe变量都会被判定为undefined,导致重复添加点击监听。

解决方案

方案1:利用DOM属性做全局标记(推荐)

DOM是所有内容脚本共享的环境,通过给页面根元素添加自定义属性来标记监听是否已初始化,避免重复添加:

修改content.js如下:

// 检查页面是否已初始化过点击监听
if (!document.documentElement.hasAttribute('data-extension-click-initialized')) {
  // 添加标记属性
  document.documentElement.setAttribute('data-extension-click-initialized', 'true');
  // 绑定点击监听
  document.addEventListener('click', () => {
    console.log('clicked!');
  });
}

方案2:优化后台脚本的注入触发逻辑

可以限制chrome.runtime.onInstalled的触发场景,仅在扩展首次安装或更新时执行注入,减少不必要的重复注入:

修改background.js如下:

chrome.runtime.onInstalled.addListener(async details => {
  // 仅在扩展安装/更新时执行注入,过滤其他触发场景(如Chrome更新)
  if (!['install', 'update'].includes(details.reason)) return;

  const contentScript = chrome.runtime.getManifest().content_scripts[0];
  const tabs = await chrome.tabs.query({ url: contentScript.matches });

  tabs.forEach(async tab => {
    if (tab.status !== 'unloaded' && !bannedURLs.some(url => tab.url.includes(url))) {
      try {
        await chrome.scripting.executeScript({
          target: { tabId: tab.id },
          files: contentScript.js
        });
      } catch (error) {
        console.log(`executeScript failed on tab ${tab.id} (${tab.url})`, error);
      }
    }
  });
});

方案3:使用Chrome存储标记状态

如果需要跨标签页同步初始化状态,可以借助chrome.storage.local存储标记(需在manifest.json中声明storage权限):

content.js修改示例:

(async () => {
  const { hasInitializedListener } = await chrome.storage.local.get('hasInitializedListener');
  if (!hasInitializedListener) {
    await chrome.storage.local.set({ hasInitializedListener: true });
    document.addEventListener('click', () => {
      console.log('clicked!');
    });
  }
})();

注意事项

  • 方案1是最轻量化的实现,无需额外权限,适合大多数场景;
  • 如果你的扩展需要在多个标签页中保持状态同步,方案3更合适,但要注意扩展卸载后需清理存储内容。

内容的提问来源于stack exchange,提问作者dem.1797

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.02 01:31:18