带有 Manifest V3 的 Chrome 扩展可以在后台修改标签吗?

Can a Chrome Extension with Manifest V3 modify tabs in the background?

我正在尝试 chrome 扩展开发,并希望制作一个扩展,以突出显示背景脚本中每个页面上的特定单词。
如果我给我的扩展程序授予 activeTab 权限,它会被列为“请求访问”,我需要通过打开弹出窗口来调用它,然后在重新加载页面后它会突出显示这个词。

documentation 说“本质上,activeTab 暂时授予 tabs 权限”,所以我切换到提供选项卡许可,因为我不想每次访问新网站时都打开弹出窗口。但是,现在扩展被列为“不需要访问”,并且无论我是否调用弹出窗口,突出显示都不起作用。

这是我的 service-worker background.js:

chrome.tabs.onUpdated.addListener(function(tabId, changeInfo, tab){
  if (changeInfo.status == 'complete') {  
    chrome.scripting.executeScript({
      target: { tabId: tabId },
      function: highlightwords,
    });
  }
})


function highlightwords(){
  var list = document.getElementsByTagName("p")
  var search_words = ["the", "it", "you"]
  var words = []

  for(var i = 0; i < list.length; i++){
    var words = list[i].textContent.split(' ')
    for (var j = 0; j < words.length; j++) {
      if (search_words.includes(words[j])) {
        console.log(words[j]);
        var elem = document.createElement("span")
        elem.textContent = words[j]
        elem.style.color = "red"
        words[j]=elem.outerHTML
      }      
    }
    
    list[i].innerHTML = words.join(' ')
  }
}

manifest.json:

{
  "name": "Getting Started Example",
  "description": "Build an Extension!",
  "version": "1.0",
  "manifest_version": 3,
  "background": {
      "service_worker": "background.js"
  },
  "action": {
    "default_popup": "popup.html",
    "default_icon": {
      "16": "/images/get_started16.png",
      "32": "/images/get_started32.png",
      "48": "/images/get_started48.png",
      "128": "/images/get_started128.png"
    }
  },
  "icons": {
    "16": "/images/get_started16.png",
    "32": "/images/get_started32.png",
    "48": "/images/get_started48.png",
    "128": "/images/get_started128.png"
  },
  "options_page": "options.html",
  "permissions": ["storage", "scripting", "tabs"]
}

我将非常感谢任何关于这里出了什么问题或有哪些替代方案的提示(除了使用清单 v2,它可能没有太大的未来,至少在 Chrome ).

tabs 权限的唯一目的是在 changeInfotab 对象中显示 url,例如在 chrome.tabs.onUpdated 事件中。您不使用它,也不需要它来完成此任务。

  1. 删除tabsscripting权限,删除后台工作者。

  2. 在manifest.json

    中声明一个content script
    "content_scripts": [{
      "matches": ["*://*/*"],
      "js": ["content.js"]
    }]
    
  3. content.js 将在所有 http/https 站点中 运行 (这是 *://*/* 中第一个 * 的意思)并突出显示正文。

P.S。请注意,您当前的代码会破坏页面添加到 p 内任何嵌套元素的事件侦听器,因为您分配给了 innerHTML。这是不好的。更好的方法是使用 DOM 方法 createTreeWalker 和 splitText,example, or just use mark.js.

替换内联文本的匹配部分