Chrome 插件在新开页生效

Chrome 插件要在当前页面生效后,对从该页面点击打开的"其他页面(新标签页或同标签页跳转)"也生效,通常取决于你的插件是如何注入脚本的。

这里有几种常见的场景和对应的解决方案(均基于目前主流的 Manifest V3):


方法一:通过 manifest.json 自动匹配匹配规则(最简单、最常用)

如果你的插件功能是始终需要 在某些特定的网站上运行的,不需要用户手动点击插件图标触发,那么直接在 manifest.json 中配置 content_scripts 即可。

json 复制代码
{
  "manifest_version": 3,
  "name": "My Extension",
  "version": "1.0",
  "content_scripts": [
    {
      "matches": [
        "*://*.example.com/*", 
        "https://www.google.com/*"
      ],
      "js": ["content.js"],
      "run_at": "document_idle"
    }
  ]
}

原理 :只要新打开的页面 URL 匹配 matches 里的规则,Chrome 就会自动将 content.js 注入到新页面中,无需额外写代码。如果想对所有网页生效,可以使用 "<all_urls>"


方法二:通过 Background 脚本监听新页面加载(适合用户手动开启/关闭的插件)

如果你的插件是:用户点击插件图标(Action)后才在当前页面生效 。那么默认情况下,新开的标签页是不会生效的。你需要通过 background.js (Service Worker) 来记住插件的"开启状态",并在新页面加载时动态注入脚本。

1. 修改 manifest.json 添加权限:

json 复制代码
{
  "permissions": ["tabs", "scripting", "storage", "activeTab"],
  "host_permissions": ["<all_urls>"],
  "background": {
    "service_worker": "background.js"
  }
}

2. 编写 background.js 你需要记录当前插件是否处于"激活"状态。

javascript 复制代码
// 监听插件图标点击事件
chrome.action.onClicked.addListener((tab) => {
  // 读取当前状态并切换
  chrome.storage.local.get(['isActive'], (result) => {
    let newState = !result.isActive;
    chrome.storage.local.set({ isActive: newState });
    
    // 如果开启,立刻对当前页面注入脚本
    if (newState) {
      injectScript(tab.id);
    }
  });
});

// 监听标签页更新(当点击链接在当前页跳转,或打开新标签页时会触发)
chrome.tabs.onUpdated.addListener((tabId, changeInfo, tab) => {
  // 确保页面加载完成,并且有 URL
  if (changeInfo.status === 'complete' && tab.url) {
    chrome.storage.local.get(['isActive'], (result) => {
      // 如果插件处于全局开启状态,则自动注入
      if (result.isActive) {
        injectScript(tabId);
      }
    });
  }
});

// 注入脚本的公共方法
function injectScript(tabId) {
  chrome.scripting.executeScript({
    target: { tabId: tabId },
    files: ['content.js']
  }).catch(err => console.log("注入失败:", err));
}

方法三:只针对"从当前已激活页面衍生出的新页面"(精准继承)

如果你不希望插件全局开启,只希望"从激活了插件的页面 A" 点击链接打开的"页面 B" 也被激活 。 你可以利用 chrome.tabs.onCreated 中的 openerTabId 属性。

background.js 中:

javascript 复制代码
// 用一个 Set 来存储被激活了插件的 Tab ID
let activeTabs = new Set();

chrome.action.onClicked.addListener((tab) => {
  // 激活当前 Tab
  activeTabs.add(tab.id);
  injectScript(tab.id);
});

// 监听新标签页被创建
chrome.tabs.onCreated.addListener((tab) => {
  // 如果新标签页是从一个已经激活的 Tab 中打开的 (openerTabId)
  if (tab.openerTabId && activeTabs.has(tab.openerTabId)) {
    // 将新标签页也加入激活列表
    activeTabs.add(tab.id);
  }
});

// 监听标签页加载完成
chrome.tabs.onUpdated.addListener((tabId, changeInfo, tab) => {
  if (changeInfo.status === 'complete' && activeTabs.has(tabId)) {
    injectScript(tabId);
  }
});

// 标签页关闭时清理内存
chrome.tabs.onRemoved.addListener((tabId) => {
  activeTabs.delete(tabId);
});

function injectScript(tabId) {
  chrome.scripting.executeScript({
    target: { tabId: tabId },
    files: ['content.js']
  });
}

方法四:应对单页面应用 (SPA) 如 Vue/React 网站

如果当前网站是单页面应用(如 Bilibili、YouTube 等),点击链接时页面并不会真正刷新,只会通过 HTML5 History API 改变 URL 并局部重新渲染 DOM。

这时上面通过 Background 监听 onUpdated 的方式可能不够及时,你需要在你的 content.js 内部进行监听:

content.js 中监听 URL 变化或 DOM 变化:

javascript 复制代码
// 1. 监听 URL 变化 (拦截 History API)
let lastUrl = location.href; 
new MutationObserver(() => {
  const url = location.href;
  if (url !== lastUrl) {
    lastUrl = url;
    onUrlChange(); // URL发生改变时重新执行你的逻辑
  }
}).observe(document, {subtree: true, childList: true});

function onUrlChange() {
  console.log("页面路由发生改变,重新应用插件效果");
  // 延迟一小段时间等待DOM渲染
  setTimeout(() => {
    applyMyExtensionLogic();
  }, 500);
}

// 你的核心逻辑
function applyMyExtensionLogic() {
  // ...改变背景色、提取数据等
}

// 初始加载执行一次
applyMyExtensionLogic();

总结建议:

  1. 静态且始终生效 :选 方法一 (manifest.json 配置 matches)。
  2. 开关控制,全平台生效 :选 方法二 (Background + chrome.storage)。
  3. 血统继承 (父传子) :选 方法三 (Background + openerTabId)。
  4. 同页面无刷新跳转失效 :选 方法四 (Content script 内 MutationObserver)。
相关推荐
weixin_382395232 小时前
为小工厂量身打造:本地部署的物料管理系统带缺料计算
前端·制造
__zRainy__2 小时前
解决pnpm v10+不自动构建
前端·pnpm·工程化
猫猫不是喵喵.3 小时前
Vue3 Props 属性
前端·javascript·vue.js
醉城夜风~4 小时前
CSS元素显示模式(display)
前端·css
AI大模型-小华4 小时前
Codex 三方充值快速入门指南
java·前端·数据库·chatgpt·ai编程·codex·chatgpt pro
做前端的娜娜子7 小时前
同一链接实现 PC Web 与移动 H5 自适应
前端·掘金·金石计划
小帅不太帅7 小时前
架构没变、规模没变,DeepSeek V4 Flash 正式版凭什么暴涨 47 分?
前端·aigc·deepseek
jarvisuni7 小时前
DeepSeekFlash前端依旧拉垮,而且变慢了很多!
前端·javascript·算法
卷福同学8 小时前
AI编程出海第二步:验证关键词能否做站
前端·人工智能·后端