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

Javascript 如何确定内容脚本中的弹出窗口中是否有Chrome扩展?,javascript,google-chrome,google-chrome-extension,Javascript,Google Chrome,Google Chrome Extension,背景 我有一个带有浏览器操作的Chrome扩展,可以在新选项卡中启动index.html 我想先将扩展名更新为openindex.html,然后添加一个按钮,用户可以单击该按钮在新选项卡中选择打开应用程序 我不希望这个按钮在不是弹出窗口时显示(因为它没有意义),这意味着内容脚本需要知道它是否是弹出窗口才能显示按钮 问题 这是一个由两部分组成的问题: Chrome扩展弹出窗口如何知道它是弹出窗口 如何在呈现弹出窗口之前将该信息传递给内容脚本 我尝试过的 我尝试在background.js中使用ch

背景

我有一个带有浏览器操作的Chrome扩展,可以在新选项卡中启动
index.html

我想先将扩展名更新为open
index.html
,然后添加一个按钮,用户可以单击该按钮在新选项卡中选择打开应用程序

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

问题

这是一个由两部分组成的问题:

  • Chrome扩展弹出窗口如何知道它是弹出窗口
  • 如何在呈现弹出窗口之前将该信息传递给内容脚本
  • 我尝试过的

    我尝试在
    background.js
    中使用
    chrome.extension.getViews
    来首先确定弹出窗口是否打开。然后,我向内容脚本发送一条消息,然后显示按钮。但是,我还没有让它工作-
    视图
    始终是一个空数组,并且内容脚本似乎从未接收到消息

    以下是我的
    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"
    }
    
    下面是我在
    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) {});  
      });
    };
    
    然后在我的内容脚本中,我侦听消息,然后向正文中添加一个类:

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

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

    我可以在
    manifest.json
    中指定
    ?popup=true
    ,并在扩展的内容脚本中检查该参数。代码如下:

    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"
    }
    
    我的内容脚本中的以下代码(取自)检查是否存在
    ?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';
    
    我最初设置按钮的
    显示:无如果返回的选项卡是未定义的,则表示它不是选项卡(因此它是弹出的),然后显示按钮。你当然可以把它倒过来

    =======

    发送参数也可以工作,在这种情况下,您不需要在清单中添加查询字符串,只需将其添加到button的click listener中即可

    btn.addEventListener('click', function() {
        chrome.tabs.create({url: "index.html?popup=false"});
    });
    
    然后执行相同的过程(读取查询字符串并进行比较等)

    =======


    或者,您可以复制
    index.html
    的副本,比如说
    index2.html
    ,从index.html中删除按钮,在清单中使用index2.html,并在index.html中单击按钮。:)

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

    "browser_action": {
      "default_popup": "index.html#popup"
    }
    
    在JavaScript中:

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

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

    我发现这很有效

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

    您好,index.html现在是您代码的弹出窗口吗?我认为它应该是一个弹出窗口,而不是一个新的标签。如果你不想在新标签页中显示按钮,你可以在点击按钮时打开新标签的链接中添加一个url参数,如“?ispoup=false”。啊,谢谢,我的一位朋友也说过同样的话——url参数方法很好用。我已经添加了它作为一个答案!只需将其作为url参数包含到弹出窗口中,不幸的是,这无法区分弹出窗口和moz等扩展页面之间的区别-extension://hashThis 真是太棒了。谢谢分享。但是有一件事-WEB和CONTENT_SCRIPT(或者这里的WEB是什么?)不一样吗?选项页呢?@bhavya_w如果您也使用脚本标记或eval将脚本注入到实际的网页中,这将是一个问题。我不确定选项。一个小的调整:应该是if(location.hash=='#popup')
    if(location.hash == 'popup') 
        // do something awesome!
    
    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';
        }
    })();