如何防止 chrome 扩展程序在同一个弹出窗口仍处于打开状态时重新打开?



我正在处理具有登录弹出窗口的chrome扩展程序。因此,这个想法是为了扩展工作,它需要用户登录,以便它可以与我们的API进行交互并获取/发布数据。

因此,我覆盖browserAction以检查用户是否已登录,如果不是,则应显示登录弹出。我的问题是,当我再次单击扩展图标时,它重新打开了相同的登录弹出窗口。我如何防止这种情况发生,并且只有一个登录窗口打开的实例?

背景.js

// omitted some codes for brevity
chrome.browserAction.onClicked.addListener(function () {
    // omitted some codes for brevity
    chrome.windows.create({ 
        'url': 'login.html', 
        'type': 'popup',
        'width': width,
        'height': height,
        'left': (screen.width/2) - (width/2),
        'top': (screen.height/2) - (height/2),
        'focused': true
    });
});

有多种方法可以做到这一点。

使用chrome.tabs.query()检测窗口是打开的

您可以通过调用chrome.tabs.query()

来检查弹出窗口的存在
var popupUrl = chrome.runtime.getURL('/login.html');
chrome.tabs.query({url:popupUrl},function(tabs){
    if(tabs.length > -1){
        //The popup exists
    }
});

为了使上述工作,您必须声明tabs许可。

但是,chrome.tabs.query()将在呼叫chrome.windows.create()和窗口实际打开的时间之间未检测到弹出窗口。基于测试,此时间足够长,可以使用户多次单击浏览器操作按钮,打开多个弹出窗口。

用全局变量跟踪弹出窗口

给定使用chrome.tabs.query()检测窗口的缺点,我的偏爱是使用全局变量保存弹出窗口的当前状态。在下面的代码中,变量popupWindowId可以具有三个通用状态:

  • false:窗口不打开
  • true:窗口正在打开的过程
  • typeof popupWindowId === 'number':弹出窗口打开。数字是窗口ID。

如果用户单击浏览器操作按钮,则用户想要弹出窗口。虽然我们不想打开一个新的弹出窗口,但我们确实想为用户提供他们想要的东西。因此,如果弹出窗口已经打开,则将弹出窗口聚焦。这将把它带到顶部,向用户展示。完整的实现还应检查弹出窗口是否在屏幕的可见范围内。如果不可见,则应将其移动为可见。此后的功能未在此处实现。

要检测何时关闭弹出窗口,使用chrome.windows.onRemoved侦听器。

我还喜欢向正在进行的用户提供反馈,因此弹出窗口的标题已更改为"弹出窗口已经打开。单击以焦点弹出窗口"。当弹出窗口打开时。关闭窗口后,标题将更改回"打开的弹出窗口"。

背景.js

var windowNotOpenTitle = 'Open popup window';
var windowIsOpenTitle = 'Popup window is already open. Click to focus popup.';
var popupWindowId = false; //popupWindowId can be true, false, or the popup's window Id.
chrome.browserAction.onClicked.addListener(function () {
    let width= 400;
    let height= 300;
    if(popupWindowId === false){
        popupWindowId = true; //Prevent user pressing pressing the button multiple times.
        chrome.browserAction.setTitle({title:windowIsOpenTitle});
        chrome.windows.create({ 
            'url': 'login.html', 
            'type': 'popup',
            'width': width,
            'height': height,
            'left': (screen.width/2) - (width/2),
            'top': (screen.height/2) - (height/2),
            'focused': true
        },function(win){
            popupWindowId = win.id;
        });
        return;
    }else if(typeof popupWindowId === 'number'){
        //The window is open, and the user clicked the button.
        //  Focus the window.
        chrome.windows.update(popupWindowId,{focused:true});
    }
});
chrome.windows.onRemoved.addListener(function (winId){
    if(popupWindowId === winId){
        //chrome.browserAction.enable();
        chrome.browserAction.setTitle({title:windowNotOpenTitle});
        popupWindowId = false;
    }
});

最新更新