首页 > 解决方案 > Chrome 扩展程序如何“侦听”主机页面上的所有 iFrame 以完成加载?

问题描述

我的 Chrome 扩展程序围绕特定 URL 包装了一个工具栏。

它调整主机页面的大小 - 为工具栏腾出空间。

扩展内容脚本被注入每一帧(不仅仅是顶部)。

我希望 Chrome 扩展程序使用的某些页面具有 iFrame,需要一段时间才能加载内容。

当 iFrame 内容最终完成加载时,其中一些页面会调整大小。如何在调整父页面大小之前监听 iFrame 完成加载?

我相信我需要让注入到页面中的每个内容脚本通过背景脚本与父页面进行通信......但我不明白如何具体,从注入页面上 iFrame 的内容脚本,消息的目标是顶级内容脚本,然后可以调整父网页的大小。

任何建议/方向表示赞赏!

更新:重复有用的答案/建议......

我不明白背景如何知道有多少 iFrame 以及页面何时真正完成加载。我修改了下面的建议,以监听完成的 iFrame 加载完成,然后查询活动选项卡以查看加载是否完成......不确定这是否是多余的......

然后后台调用内容脚本要求它调整窗口大小。

这显示出一些希望,但我必须重新连接其他一些东西以确保它会起作用。

对这种方法的想法?

chrome.webNavigation.onCompleted.addListener(info => {
  console.log('WEB navigation complete...?', info);
  // if (info.frameId) {
    // chrome.tabs.sendMessage(info.tabId, {cmd: 'frameLoaded'}, {frameId: 0});
    chrome.tabs.query({active: true, currentWindow: true}, function(tabs) {
      console.log('Message current window to resize the window...', tabs[0].status);
      if (tabs[0].status === "complete"){
        try {
          chrome.tabs.sendMessage(tabs[0].id, {method: "resizeWindow"});
        } catch (err){
          console.log('Could not message content script because: ' + err);
        }
      }
    });
  // }
});

标签: javascriptgoogle-chrome-extension

解决方案


您可以在后台脚本中使用senderonMessage侦听器来识别消息的选项卡(sender.tab.id)并将其重新发送到顶部内容脚本(frameId 0)。

chrome.runtime.onMessage.addListener((msg, sender, sendResponse) => {
  if (msg.cmd === 'frameLoaded') {
    chrome.tabs.sendMessage(sender.tab.id, msg, {frameId: 0});
  }
});

但是,最好在后台脚本中使用chrome.webNavigation.onCompleted来检测 iframe 的加载事件,而无需在 iframe 内运行内容脚本。

chrome.webNavigation.onCompleted.addListener(info => {
  if (info.frameId) {
    chrome.tabs.sendMessage(info.tabId, {cmd: 'frameLoaded'}, {frameId: 0});
  }
});
  • frameId: 0发送到主页的内容脚本,而不是 iframe
  • 不要忘记"permissions"按照文档中的说明添加 manifest.json

另一种可能性是通过(更多信息load)在 iframe 的内容脚本和 DOM 消息传递中使用事件侦听器,但某些站点会在控制台中发送垃圾邮件错误,因为它们已经使用了您无法预料和提供的某些属性。理论上,有些网站甚至可能因此而崩溃。top.postMessagemessage


推荐阅读