首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >保证一次最多打开一个铬扩展弹出页面

保证一次最多打开一个铬扩展弹出页面
EN

Stack Overflow用户
提问于 2021-10-18 09:43:37
回答 1查看 161关注 0票数 0

在我的铬扩展,我有一个弹出页面和背景脚本。

默认情况下,当我在两个不同的窗口中单击扩展的图标时,将在两个窗口中打开一个弹出窗口。我想把分机打开的弹出窗口的数量限制为一次最多一个。

下面是我试图创建的完整场景:

一开始没有弹出是activated.

  • Window A打开了popup.

  • Window B打开了一个弹出窗口,在这种情况下,Window A的弹出将close.

  • Window C创建,转到2,但是这次Window A<-Window BWindow B<-Window C

  • If在任何时候打开的唯一弹出窗口都关闭了,返回到1.

我知道创建了一个弹出窗口,因为我有一个在弹出启动时调用的简单端口连接。因此,理论上,后台知道创建的所有弹出窗口,即我在弹出窗口中运行的连接代码:

代码语言:javascript
复制
const port = chrome.runtime.connect({ name: 'popup-communications' });

我试图用三种方法解决这个问题,但都失败了。

尝试1保存最后一个已连接的弹出窗口。如果出现新的,请在保存新的之前关闭旧的。使用chrome.extension.getViews获得新端口。我原以为这是可行的,但快速单击扩展图标(以调用browserAction)使popUp状态变得混乱。

代码语言:javascript
复制
let popUp;
chrome.runtime.onConnect.addListener(function connect(port) {
  if (port.name === 'popup-communications') {
    // attempt 1
    if (popUp) {
      popUp?.close?.();
      popUp = null;
      console.log('removed old pop up');
    }
    [popUp] = chrome.extension.getViews({
      type: 'popup',
    });
});

尝试2关闭从chrome.extension.getView收到的所有弹出窗口,但关闭最后一个弹出窗口。这种方法的问题是,chrome.extension.getView不保证任何订单。

代码语言:javascript
复制
let popUp;
chrome.runtime.onConnect.addListener(function connect(port) {
  if (port.name === 'popup-communications') {
    // attempt 2
    const popUps = chrome.extension.getViews({
      type: 'popup',
    });
    console.log(popUps);
    for (let i = 0; i < popUps.length - 1; i++) {
      popUps[i].close();
    }
});

我还试验了chrome.browserAction.disablechrome.browserAction.enable。这个解决方案实际上一直维护一个弹出窗口,但是每当我单击扩展图标时,我希望弹出窗口是可用的,这种方法不会发生这种情况(相反,我需要用这个弹出窗口找到相关的窗口)。

有什么办法能达到我在这里想做的吗?

EN

回答 1

Stack Overflow用户

发布于 2021-10-18 15:41:10

我能够通过以下方式实现这一行为。

background.js

后台侦听连接弹出窗口。

当弹出窗口连接时,它将向所有打开的弹出窗口广播一条消息以关闭。注意,由于端口连接不广播,因此不会通过端口发送此消息。

应该有一种优化的方法,因为最多可以打开另一个弹出窗口,但是我将把它留到下一次,而不希望创建全局变量。

代码语言:javascript
复制
chrome.runtime.onConnect.addListener(function connect(port) {
    if (port.name === 'popup-communications') {

        port.onMessage.addListener(function (msg) {
            if (msg.here) {
                const activeTabId = msg.here;

                // broadcast close request
                chrome.runtime.sendMessage({closeUnmatched: activeTabId});
            }
        });
    }
});

popup.js

  1. 对其选项卡id.

执行查找。

  1. 添加消息侦听器以知道何时关闭。如果要关闭的消息与当前选项卡id不匹配,弹出窗口将关闭。window.close()足以关闭弹出窗口.

  1. 向后台“宣布”,通过端口发送标签Id,弹出窗口已经准备好了。

代码语言:javascript
复制
async function getCurrentTab() {
    let queryOptions = {active: true, currentWindow: true};
    let [tab] = await chrome.tabs.query(queryOptions);
    return tab;
}

function addListener(myTabId) {
    chrome.runtime.onMessage.addListener(function (msg) {
        if (msg.closeUnmatched && msg.closeUnmatched !== myTabId) {
            window.close();
        }
    });
}

(async function constructor() {
    const port = chrome.runtime.connect({name: 'popup-communications'});

    // whoami lookup
    const {id: myTabId} = await getCurrentTab();

    // add handler to self-close
    addListener(myTabId);

    // tell background I'm here
    port.postMessage({here: myTabId});

    // do whatever with port..
}());

我假设步骤1-3可以比用户切换选项卡/窗口更快地激活另一个弹出窗口。端口连接使事情变得复杂,但我把它留在了答案中,因为您可能对它有一个用例。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/69613914

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档