如何确定 Chrome 扩展程序是否在内容脚本的弹出窗口中?

Ben*_*rey 5 javascript google-chrome google-chrome-extension

背景

我有一个带有浏览器操作的 Chrome 扩展程序,可以index.html在新标签页中启动。

我想更新扩展程序以首先index.html弹出窗口中打开,然后包含一个按钮,用户可以单击以选择性地在新选项卡中打开应用程序。

我不希望这个按钮在它不是弹出窗口时显示(因为它没有意义),这意味着内容脚本需要知道它是否是一个弹出窗口才能显示按钮。

问题

这是一个两部分的问题:

  1. Chrome 扩展弹出窗口如何知道它是一个弹出窗口?
  2. 如何在呈现弹出窗口之前将该信息传递给内容脚本?

我试过的

我尝试使用chrome.extension.getViewsinbackground.js首先确定弹出窗口是否打开。然后,我向内容脚本发送一条消息,然后显示该按钮。但是我还没有让它工作 -views总是一个空数组,并且内容脚本似乎永远不会收到消息。

以下是我的manifest.json文件的相关部分:

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

"browser_action": {
  "default_icon": {   
    "19": "img/icon19.png",
    "38": "img/icon38.png"
  },

  "default_title": "Super Simple Tasks",

  "default_popup": "index.html"
}
Run Code Online (Sandbox Code Playgroud)

这是我一直在尝试的内容background.js

// Get all popups
var views = chrome.extension.getViews({ type: "popup" });

// Send a message if there is a popup
if (views.length > 0){
  chrome.tabs.query({active: true, currentWindow: true}, function(tabs){
    chrome.tabs.sendMessage(tabs[0].id, {action: "popup_open"}, function(response) {});  
  });
};
Run Code Online (Sandbox Code Playgroud)

然后在我的内容脚本中,我侦听消息,然后向正文添加一个类:

// Listen for the message
chrome.extension.onMessage.addListener(function(msg, sender, sendResponse) {
  if (msg.action === 'popup_open') {
    // My code here to show the button
  }
});
Run Code Online (Sandbox Code Playgroud)

Tho*_*ran 7

在清单文件中向 url 添加哈希:

"browser_action": {
  "default_popup": "index.html#popup"
}
Run Code Online (Sandbox Code Playgroud)

在 JavaScript 中:

if (location.hash === '#popup') 
    // do something awesome!
Run Code Online (Sandbox Code Playgroud)

  • 一个小调整:应该是 if (location.hash == '#popup') (2认同)

Ben*_*rey 5

在与朋友交谈后,我发现了一个优雅的解决方案,它根本不涉及消息传递甚至background.js脚本。

我可以?popup=truemanifest.json扩展程序的内容脚本中指定并检查该参数。这是代码:

manifest.json 现在看起来像这样:

"browser_action": {
  "default_icon": {   
    "19": "img/icon19.png",
    "38": "img/icon38.png"
  },

  "default_title": "Super Simple Tasks",

  "default_popup": "index.html?popup=true"
}
Run Code Online (Sandbox Code Playgroud)

我的内容脚本中的以下代码(取自此答案)检查?popup=true. 值得注意的是,该函数可以处理多个按&字符分割的 URL 参数。

function getUrlParameter(sParam) {
  var sPageURL = window.location.search.substring(1);
  var sURLVariables = sPageURL.split('&');
  for (var i = 0; i < sURLVariables.length; i++) {
    var sParameterName = sURLVariables[i].split('=');
    if (sParameterName[0] == sParam) {
      return sParameterName[1];
    }
  }
}

var isPopup;
isPopup = getUrlParameter('popup') === 'true';
Run Code Online (Sandbox Code Playgroud)

最后,如果它是一个弹出窗口,则向主体添加一个类:

$('body').toggleClass('popup', isPopup)
Run Code Online (Sandbox Code Playgroud)


Cha*_*ira 5

我需要类似的东西,因为我想为所有脚本类型创建一些交叉兼容的代码。

我发现这很有效。

const SCRIPT_TYPE = (() => {
    if (chrome && chrome.extension && chrome.extension.getBackgroundPage && chrome.extension.getBackgroundPage() === window) {
        return 'BACKGROUND';
    } else if (chrome && chrome.extension && chrome.extension.getBackgroundPage && chrome.extension.getBackgroundPage() !== window) {
        return 'POPUP';
    } else if (!chrome || !chrome.runtime || !chrome.runtime.onMessage) {
        return 'WEB';
    } else {
        return 'CONTENT';
    }
})();
Run Code Online (Sandbox Code Playgroud)