简体   繁体   English

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

[英]How can I determine if a Chrome extension is in a popup from the content script?

Background 背景

I have a Chrome extension with a browser action to launch index.html in a new tab. 我有一个Chrome扩展程序,其浏览器操作可在新标签页中启动index.html

I'd like to update the extension to open index.html in a popup first, and then include a button users can click to optionally open the app in a new tab. 我想首先在弹出窗口中更新扩展名以打开index.html ,然后包含一个按钮,用户可以单击该按钮以选择性地在新选项卡中打开该应用程序。

I don't want this button to show when it's not a popup (since it wouldn't make sense), which means the content script needs to know whether it is a popup in order to show the button. 我不希望这个按钮显示它不是一个弹出窗口(因为它没有意义),这意味着内容脚本需要知道它是否是一个弹出窗口才能显示按钮。

Questions 问题

This is a two part question: 这是一个两部分问题:

  1. How does a Chrome extension popup know it's a popup? Chrome扩展弹出窗口如何知道它是弹出窗口?
  2. How do I pass that information to a content script before the popup is rendered? 在呈现弹出窗口之前,如何将该信息传递给内容脚本?

What I've tried 我试过的

I've tried to use chrome.extension.getViews in background.js to firstly determine if a popup is open. 我试图在background.js使用chrome.extension.getViews来首先确定弹出窗口是否打开。 Then, I send a message to the content script which then shows the button. 然后,我向内容脚本发送一条消息,然后显示该按钮。 However I haven't gotten it to work - views is always an empty array, and the message doesn't seem to ever be received by the content script. 但是我没有让它工作 - views总是一个空数组,并且内容脚本似乎从未接收过该消息。

Here are the relevant parts of my manifest.json file: 以下是我的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"
}

And here's what I've been trying in my background.js : 这就是我在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) {});  
  });
};

And then in my content script, I listen for the message and then add a class to the body: 然后在我的内容脚本中,我监听消息,然后向正文添加一个类:

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

After talking with a friend I discovered an elegant solution that doesn't involve messaging or even a background.js script at all. 在与朋友交谈后,我发现了一个优雅的解决方案,它根本不涉及消息传递甚至是background.js脚本。

I can specify ?popup=true in manifest.json and check for that parameter in my extension's content script. 我可以在manifest.json指定?popup=true ,并在我的扩展内容脚本中检查该参数。 Here's the code: 这是代码:

manifest.json now looks like this: 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"
}

The following code in my content script (taken from this answer ) checks for ?popup=true . 我的内容脚本中的以下代码(取自此答案 )检查?popup=true Worth noting that this function can handle multiple URL parameters split by the & character. 值得注意的是,此函数可以处理由&字符分割的多个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';

Finally, add a class to the body if it's a popup: 最后,如果它是弹出窗口,则向主体添加一个类:

$('body').toggleClass('popup', isPopup)
chrome.tabs.getCurrent(function(tab) {
    if(tab == undefined)
        document.getElementById('mButton').style.display = 'inline-block';
});

I initially set the button's display: none; 我最初设置按钮的display: none; if the returned tab is undefined , means it's not a tab (so it is popup) and then I display button. 如果返回的选项卡undefined ,则表示它不是选项卡(因此它是弹出窗口)然后我显示按钮。 You can reverse it of course. 你当然可以改变它。

====== ======

Well the sending parameter also works, which in that case you won't need to add the query string in the manifest, just adding it in button's click listener would suffice. 那么发送参数也可以工作,在这种情况下你不需要在清单中添加查询字符串,只需在按钮的点击监听器中添加它就足够了。

btn.addEventListener('click', function() {
    chrome.tabs.create({url: "index.html?popup=false"});
});

And then the same process (reading the query string and comparing, etc). 然后是相同的过程(读取查询字符串并进行比较等)。

====== ======

Alternatively you can make a copy of index.html say index2.html , remove the button from index.html, use index2.html in the manifest and index.html for button click. 或者,您可以复制index.htmlindex2.html ,从index.html中删除按钮,在清单和index.html中使用index2.html进行按钮单击。 :) :)

I needed something similar as i wanted to create some cross-compatible code for all script types. 我需要类似的东西,因为我想为所有脚本类型创建一些交叉兼容的代码。

I found that this worked quite well. 我发现这很有效。

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';
    }
})();

In the manifest file add a hash to the url: 在清单文件中添加一个哈希到url:

"browser_action": {
  "default_popup": "index.html#popup"
}

In JavaScript: 在JavaScript中:

if(location.hash == 'popup') 
    // do something awesome!

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 Chrome扩展程序:如何响应内容脚本中的“弹出”操作? - Chrome extension: How to respond to the action from “popup” in the content script? 从扩展程序到内容脚本的Chrome扩展消息传递 - Chrome extension messaging from popup to content script 无法将鼠标坐标从 content_script 传递到弹出窗口(chrome 扩展) - can't pass mouse coordinates from content_script to popup (chrome extension) 将控件从弹出窗口转移到内容脚本 - Google Chrome扩展程序 - Transfer control from popup to content script - Google Chrome Extension chrome扩展,可将消息从弹出窗口发送到内容脚本 - chrome extension to Send Message from popup to content script Chrome 扩展传递变量从 popup.js 到内容脚本 - Chrome Extension Pass Variable from popup.js to content script 从内容脚本到Google Chrome扩展程序中的弹出窗口,点击事件均不起作用 - Click event is not working from content script to popup on Google Chrome Extension Chrome 扩展 - 从弹出窗口到内容脚本的消息传递 - Chrome Extension - Message Passing from Popup to Content Script 如何在后台获取chrome扩展程序的内容脚本? - How can I get chrome extension's content script to in the background? "<i>How can I fetch data in my content script?<\/i>如何在我的内容脚本中获取数据?<\/b> <i>(chrome extension)<\/i> (镀铬扩展)<\/b>" - How can I fetch data in my content script? (chrome extension)
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM