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

Chrome扩展自定义Div点击无法关闭问题求助(含报错)

Chrome扩展点击自定义Div关闭功能报错解决方法

我开发了一款Chrome扩展,点击扩展图标时会激活'ON'徽章并插入focus-mode.css使扩展生效;再次点击则关闭扩展(清空徽章文本并移除CSS),这部分功能正常。但激活扩展时插入的Div点击后无法关闭扩展,还报错:Uncaught TypeError: Cannot read properties of undefined (reading 'removeCSS')。

报错原因

你通过chrome.scripting.executeScript注入的getTitle函数属于内容脚本,而chrome.scripting、chrome.action这类API只能在扩展的**后台服务工作者(Service Worker)**中调用,内容脚本没有权限直接访问这些API,所以会出现undefined的报错。

解决方案:用消息通信实现跨脚本调用

内容脚本点击Div时给后台发消息,后台收到消息后执行移除CSS、更新徽章的操作,同时清理页面上的Div。

修改后的后台脚本(service-worker.js)

chrome.runtime.onInstalled.addListener(() => {
  chrome.action.setBadgeText({
    text: ''
  });
});

// 监听扩展图标点击
chrome.action.onClicked.addListener(async (tab) => {
  const prevState = await chrome.action.getBadgeText({ tabId: tab.id });
  const nextState = prevState === 'ON' ? '' : 'ON';

  await chrome.action.setBadgeText({
    tabId: tab.id,
    text: nextState
  });

  if (nextState === 'ON') {
    // 注入独立的内容脚本文件
    await chrome.scripting.executeScript({
      files: ['content-script.js'],
      target: { tabId: tab.id }
    });

    await chrome.scripting.insertCSS({
      files: ['focus-mode.css'],
      target: { tabId: tab.id }
    });
  } else if (nextState === '') {
    // 关闭时通知内容脚本移除Div
    chrome.tabs.sendMessage(tab.id, { action: 'cleanup' });
    await chrome.scripting.removeCSS({
      files: ['focus-mode.css'],
      target: { tabId: tab.id }
    });
  }
});

// 监听内容脚本发来的关闭请求
chrome.runtime.onMessage.addListener(async (message, sender) => {
  if (message.action === 'turnOffExtension') {
    const tabId = sender.tab.id;
    // 更新徽章为空
    await chrome.action.setBadgeText({
      tabId: tabId,
      text: ''
    });
    // 移除CSS
    await chrome.scripting.removeCSS({
      files: ['focus-mode.css'],
      target: { tabId: tabId }
    });
    // 通知内容脚本移除Div
    chrome.tabs.sendMessage(tabId, { action: 'cleanup' });
  }
});

独立内容脚本文件(content-script.js)

function createExitDiv() {
  // 避免重复创建按钮
  if (document.querySelector('.exit-button')) return;

  const exitDiv = document.createElement('div');
  exitDiv.textContent = "Exit Extension";
  exitDiv.classList.add('exit-button');
  document.body.appendChild(exitDiv);

  exitDiv.addEventListener('click', () => {
    // 给后台发送关闭扩展的请求
    chrome.runtime.sendMessage({ action: 'turnOffExtension' });
  });
}

// 监听后台的清理指令,移除页面上的Div
chrome.runtime.onMessage.addListener((message) => {
  if (message.action === 'cleanup') {
    const exitDiv = document.querySelector('.exit-button');
    if (exitDiv) exitDiv.remove();
  }
});

// 初始化创建退出按钮
createExitDiv();

额外说明

  1. 把原getTitle函数抽成独立的content-script.js文件,避免用func注入,代码更易维护和调试。
  2. 内容脚本仅负责页面元素操作和消息发送,所有涉及扩展API的逻辑都交给后台处理。
  3. 增加了重复创建Div的判断,防止多次点击图标生成多个按钮。
  4. 无论是点击图标还是Div关闭扩展,都会同步清理页面上的退出按钮,保持状态一致。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.01 18:45:53