【问题标题】:How to prevent chrome extension to reopen the same popup window while it's still open?如何防止 chrome 扩展在仍然打开时重新打开同一个弹出窗口?
【发布时间】:2016-12-17 02:53:16
【问题描述】:

我正在开发一个带有登录弹出窗口的 chrome 扩展程序。所以这个想法是让扩展工作它需要用户登录,以便它可以与我们的 API 交互并获取/发布数据。

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

background.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.windows.create 前添加if 并检查窗口是否尚未打开?
  • 我可以这样做,但我怎么知道我正在检查的窗口是否是登录窗口?
  • 嗯。我想我只需要chrome.windows.create 函数之外的变量,并在其回调中使用它来获取它的 id,以便我可以检查它是否打开?

标签: javascript google-chrome google-chrome-extension


【解决方案1】:

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

使用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 侦听器。

我还想向用户提供正在发生的事情的反馈,因此弹出窗口的标题更改为“弹出窗口已打开。单击以聚焦弹出窗口。”弹出窗口打开时。当窗口关闭时,标题改回“打开弹出窗口”。

background.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;
    }
});

【讨论】:

  • 为什么是popupWindowId === false 而不是!popupWindowId
  • @rpmansion,因为popupWindowId 可以是booleannumber可能的窗口 ID 包括 0,如果您使用 !popupWindowId,则其计算结果为 true (!falsy)。如果使用popupWindowId === 0,则使用!popupWindowId 将导致打开一个额外的窗口。几乎可以肯定,这永远不会发生,但为什么要碰巧呢。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-11-20
  • 2022-06-16
  • 1970-01-01
相关资源
最近更新 更多