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

如何在Chrome Extension MV3的background.js中获取系统明暗主题设置?

解决MV3后台脚本无法检测系统主题变化的问题

由于MV3的后台脚本运行在Service Worker环境中,没有window对象,因此无法直接调用window.matchMedia。以下是两种可靠的解决方案:

方案一:使用Offscreen Document(推荐,持久监听)

Offscreen Document是MV3新增的API,用于替代原background.html的部分场景,可在独立页面环境中运行代码,支持window相关API。

1. 修改manifest.json配置

添加offscreen权限和文档路径:

{
  "manifest_version": 3,
  "permissions": ["offscreen"],
  "background": {
    "service_worker": "background.js"
  },
  "offscreen": {
    "page": "offscreen.html",
    "persistent": false
  }
}

2. 创建offscreen.html

<!DOCTYPE html>
<html>
<body>
  <script src="offscreen.js"></script>
</body>
</html>

3. 编写offscreen.js(监听主题变化并通知后台)

const mediaQuery = window.matchMedia('(prefers-color-scheme: dark)');

// 向后台发送主题状态
function sendThemeUpdate(isDark) {
  chrome.runtime.sendMessage({ type: 'theme_updated', isDark });
}

// 初始发送一次当前主题状态
sendThemeUpdate(mediaQuery.matches);

// 监听主题变化
mediaQuery.addEventListener('change', (e) => {
  sendThemeUpdate(e.matches);
});

4. 修改background.js(接收消息并更新图标)

// 确保offscreen文档已加载
async function initOffscreen() {
  if (await chrome.offscreen.hasDocument()) return;
  await chrome.offscreen.createDocument({
    url: 'offscreen.html',
    reasons: ['USER_INTERFACE'],
    justification: '监听系统主题变化以同步扩展图标'
  });
}

// 接收来自offscreen的主题消息,更新扩展图标
chrome.runtime.onMessage.addListener((msg) => {
  if (msg.type === 'theme_updated') {
    const iconPath = msg.isDark ? 'icons/dark.png' : 'icons/light.png';
    chrome.action.setIcon({ path: iconPath });
  }
});

// 后台启动时初始化offscreen
(async () => {
  await initOffscreen();
})();

方案二:使用Content Script + Storage(依赖网页环境)

如果你的扩展已包含内容脚本,可利用网页环境的window对象监听主题变化,再通过Storage同步到后台。

1. 修改manifest.json配置

添加content script和storage权限:

{
  "manifest_version": 3,
  "content_scripts": [
    {
      "matches": ["<all_urls>"],
      "js": ["content-script.js"],
      "run_at": "document_start"
    }
  ],
  "permissions": ["storage"]
}

2. 编写content-script.js(监听主题变化并更新Storage)

const mediaQuery = window.matchMedia('(prefers-color-scheme: dark)');

// 更新Storage中的主题状态
function syncThemeToStorage(isDark) {
  chrome.storage.local.set({ isDarkTheme: isDark });
}

// 初始同步一次
syncThemeToStorage(mediaQuery.matches);

// 监听主题变化并同步
mediaQuery.addEventListener('change', (e) => {
  syncThemeToStorage(e.matches);
});

3. 修改background.js(监听Storage变化并更新图标)

// 初始获取主题状态并设置图标
chrome.storage.local.get('isDarkTheme', (res) => {
  const isDark = res.isDarkTheme ?? false; // 默认浅色主题
  const iconPath = isDark ? 'icons/dark.png' : 'icons/light.png';
  chrome.action.setIcon({ path: iconPath });
});

// 监听Storage变化,实时更新图标
chrome.storage.onChanged.addListener((changes) => {
  if (changes.isDarkTheme) {
    const isDark = changes.isDarkTheme.newValue;
    const iconPath = isDark ? 'icons/dark.png' : 'icons/light.png';
    chrome.action.setIcon({ path: iconPath });
  }
});

注意:方案二的局限性在于,若用户未打开任何网页,Content Script无法运行,无法监听主题变化。因此更推荐方案一。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.02 11:33:13