【问题标题】:How to update HTML in inactive chrome tab with extension如何使用扩展名更新非活动 chrome 选项卡中的 HTML
【发布时间】:2021-06-25 16:40:22
【问题描述】:

我目前正在尝试制作 Chrome 扩展程序,但遇到了一个问题,我不知道如何从非活动选项卡更新 HTML。我正在尝试在非活动标签中定期访问 Google Meet 的 HTML,以检测人们何时离开或加入通话。但是,document.querySelector 仅在选项卡获得焦点时才起作用,就好像它没有获得焦点一样,它只会继续提供与上次获得焦点时相同的信息,即使从那时起人们已经离开或加入了通话。有什么方法可以检测这些更改而无需关注选项卡?这是我在代码中尝试过的:

background.js

meetTab = []
// check for google meet tabs
function query()
{
    meetTab = []
    chrome.tabs.query({url: "https://meet.google.com/*-*"},function(tabs)
    {
        tabs.forEach(function(tab)
        {
            meetTab.push(tab)
        });
    })
}
chrome.tabs.onCreated.addListener(query)
chrome.tabs.onRemoved.addListener(query)
chrome.runtime.onStartup.addListener(query)
setInterval(send, 3000)
// execute script for each google meet tab every 3 sec
function send()
{

    meetTab.forEach(function(tab)
    {
        chrome.tabs.executeScript(tab.id, {file: "check.js"})
    })
}
// this part only prints updated info when meet tab is active
chrome.runtime.onMessage.addListener(function(message, sender, sendResponse) {
    console.log(message)
});

check.js

// element to be tracked
thing = document.querySelector("#ow3 > div.T4LgNb > div > div:nth-child(9) > div.crqnQb > div.rG0ybd.xPh1xb.P9KVBf.LCXT6 > div.TqwH9c > div.SZfyod > div > div > div:nth-child(2) > div > div")
chrome.runtime.sendMessage({msg:thing.innerText})

manifest.json

{
  "manifest_version": 2,
  "name": "Meet Kicker",
  "version": "1.0",
  "icons": {"128": "bigicon.png"},
  "browser_action": {
    "default_icon": "smallicon.png",
    "default_popup": "popup.html"
  },
  "permissions": ["storage", "tabs", "<all_urls>"],

  "background":
  {
    "scripts": [
      "background.js"
    ]
  }
}

更新 check.js 尝试使用 MutationObserver

thing = document.querySelector("#ow3 > div.T4LgNb > div > div:nth-child(9) > div.crqnQb > div.rG0ybd.xPh1xb.P9KVBf.LCXT6 > div.TqwH9c > div.SZfyod > div > div > div:nth-child(2) > div > div")

var observer = new MutationObserver(function(mutations) {
  mutations.forEach(function(mutation) {
            chrome.runtime.sendMessage({msg:thing.innerText})

      });
    });

observer.observe(thing, { characterData: true, attributes: false, childList: false, subtree: true });

【问题讨论】:

    标签: javascript html google-chrome google-chrome-extension


    【解决方案1】:

    我会稍微回顾一下。

    稍微整理一下或许能解决问题。

    首先我要删除“onRemoved”事件处理程序,我看不出它如何达到目的。

    然后我会查看“onCreated”事件处理程序,以免将内容脚本 (CS) 重新注入到所有包含 Google Meet (GM) 的选项卡中,而只注入到新打开的选项卡中 (仅当 GM 明显加载在后者中时)。

    我会添加 onUpdate 事件处理程序,因为如果通过在其中加载 GM 来更新选项卡,那么最好将 CS 注入之前不存在的位置。

    现在让我们谈谈 setInterval(这可能是您所有\许多问题的原因)。
    这里我们需要了解一件事(我声明我不太了解GM)。
    Q1:你想通过querySelector检查的节点是否在你已经注入的页面中? CS 还是停留在 (i) 框架中?
    Q2:包含该节点的页面或 (i) 框架是否会随着时间的推移重新加载? (您可以使用 devtools 网络面板或使用事件处理程序(例如 tabs.onUpdate 或 webNavigation.onComplete)查看此内容)

    如果被监控的节点属于周期性重新加载的页面,那么周期性地重新注入CS是正确的。 (您可以在 onUpdate 事件处理程序中进行管理,而不是使用 setInterval)。

    另一方面,如果包含(或将包含)该节点的页面未重新加载,因此该节点出现在无法先验确定的时刻 那么您不必重新注入而是“观察”DOM 的突变(实际上您必须使用 MutationObsever 对象)。

    最后,我建议您检查您是否安装了优化 CPU 和内存的扩展程序,这可能会以某种方式干扰您的代码。

    【讨论】:

    • 我尝试将其更改为使用 onUpdated 而不是 setInterval 来注入脚本,在运行了一堆之后我发现当有人加入谷歌会议时也会调用 onUpdated,但在他们离开时不会调用,大概是因为有人加入时选项卡发出的声音,因为有人离开时没有一个?无论如何,我尝试使用 MutationObserver,不幸的是它似乎只在选项卡处于活动状态时触发。如果我在另一个选项卡上,则不会调用侦听器,直到我切换回 google meet 选项卡以检测任何更改。你知道为什么会这样吗?
    • 哦,我检查了,我很确定我检查的节点不在任何类型的框架中?我只是不确定从这里到哪里去,因为似乎选项卡的 HTML 在我选择它之前不会更新,除了 onUpdated 检测人们何时加入会议的情况。
    • 根据您所说的,我确认这些准则。每次重新加载页面时以及在任何地方注入 CS;重要的是您不会丢失对节点的跟踪(用于 querySelector 的路径必须保持不变)。如果您必须处理多个帧,最好有选择地注入,以避免 CS 和后台脚本之间出现多个消息。在 CS 中,您立即检查节点是否存在,然后将“等待工作”委托给“观察者”。
    • 有可能新参与者会重新加载页面,而离开房间的联系人不会重新加载页面,而只会更改 DOM。您可以通过 devtools 的 Network 面板模拟离开和加入房间的人来验证这一点。也有可能每次参与者离开组时,至少在选项卡变为活动状态之前,他都不会触发 mutationObserver。这种行为可能是 GM 故意设计的;如果是这样,我知道您对此无能为力。如果不将其激活,则无法激活选项卡。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-12-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多