在Chrome中检测被阻止的弹窗

106

我知道一些用于在其他浏览器中检测弹出窗口是否被阻止的JavaScript技术(如此问题的答案中所述)。这是基本测试:

var newWin = window.open(url);

if(!newWin || newWin.closed || typeof newWin.closed=='undefined')
{
    //POPUP BLOCKED
}

但这在Chrome中不起作用。当弹出窗口被阻止时,永远不会到达“POPUP BLOCKED”部分。

当然,在某种程度上,测试是有效的,因为Chrome实际上没有阻止弹出窗口,而是在右下角的小型最小化窗口中打开它,列出“已阻止”的弹出窗口。

我想做的是能够判断Chrome的弹出窗口拦截器是否阻止了弹出窗口。 我尽量避免使用浏览器嗅探,而是采用特性检测的方式。 有没有一种方法可以在不使用浏览器嗅探的情况下实现这一点?

编辑:我现在尝试利用newWin.outerHeightnewWin.left和其他类似的属性来完成此操作。 当弹出窗口被阻止时,Google Chrome将所有位置和高度值都返回为0。

不幸的是,即使弹出窗口实际上已经打开了未知的时间,它也会返回相同的值。在某个神奇的时段(在我的测试中为几秒钟),位置和大小信息将返回为正确的值。 换句话说,我仍然无法更接近解决这个问题。 谢谢任何帮助。


InvisibleBacon和Andy最新的解决方案在Chrome 10中无法工作:“failed for chrome”消息出现,即使测试弹出窗口已成功显示。有什么想法吗? - user671590
我认为需要提出一个新的问题,因为这些解决方案似乎只适用于早期版本的Chrome。 - 700 Software
1
@George Bailey 我同意,但是为了明确起见,它们中的一些在当前版本的Chrome(19)中确实有效。安德鲁最初使用outerHeight(或其他人建议的screenX)的想法对我来说运行良好,结合setTimeout方法。但是,是的,在我进行自己的测试之前,尝试理解所有这些答案确实令人困惑。 - regularmike
试试这个:https://dev59.com/5oPba4cB1Zd3GeqPxc8y#31299484 - Vlada
1
这个回答解决了你的问题吗?如何检测浏览器是否阻止弹出窗口? - Michael Freidgeim
显示剩余2条评论
16个回答

2

哇,这里有很多解决方案。这是我的解决方案,它使用了从当前被接受的答案中获取的解决方案(在最新版本的Chrome中不起作用,并且需要将其包装在超时内),以及此线程上的相关解决方案(实际上是原生JS,而不是jQuery)。

我的解决方案使用回调架构,当弹出窗口被阻止时发送true,否则发送false

window.isPopupBlocked = function(popup_window, cb)
{
    var CHROME_CHECK_TIME = 2000;       // the only way to detect this in Chrome is to wait a bit and see if the window is present

    function _is_popup_blocked(popup)
    {
        return !popup.innerHeight;
    }

    if (popup_window) {
        if (popup_window.closed) {
            // opened OK but was closed before we checked
            cb(false);
            return;
        }
        if (/chrome/.test(navigator.userAgent.toLowerCase())) {
            // wait a bit before testing the popup in chrome
            setTimeout(function() {
                cb(_is_popup_blocked(popup_window));
            }, CHROME_CHECK_TIME);
        } else {
            // for other browsers, add an onload event and check after that
            popup_window.onload = function() {
                cb(_is_popup_blocked(popup_window));
            };
        }
    } else {
        cb(true);
    }
};

2

检查窗口相对于父级的位置。Chrome使窗口几乎完全出屏幕。


我会尝试并告诉您我的结果。谢谢。 - Andrew Ensley
当弹出窗口被“阻止”时,Google Chrome报告左偏移量和顶部偏移量为0。我以为这是我的救星,但事实并非如此。在实际打开后,它立即将偏移量报告为0。在未来的某个魔法时刻,在打开后正确报告顶部和左侧偏移量。 - Andrew Ensley
请查看我的帖子,其中提供了一种似乎可以确保在检查之前设置偏移量的方法。 - InvisibleBacon

1
function openPopUpWindow(format)
{   
    var win = window.open('popupShow.html',
                          'ReportViewer',
                          'width=920px,height=720px,left=50px,top=20px,location=no,directories=no,status=no,menubar=no,toolbar=no,resizable=1,maximize:yes,scrollbars=0');

    if (win == null || typeof(win) == "undefined" || (win == null && win.outerWidth == 0) || (win != null && win.outerHeight == 0) || win.test == "undefined") 
    {
        alert("The popup was blocked. You must allow popups to use this site.");  
    }
    else if (win)
    {
        win.onload = function()
        {          
            if (win.screenX === 0) {
                alert("The popup was blocked. You must allow popups to use this site.");
                win.close();
            } 
        };
    }
}

1

我稍微修改了上面描述的解决方案,并认为它至少适用于Chrome。 我的解决方案是用来检测当打开主页面时是否被阻止弹出窗口,而不是在弹出窗口打开时,但我相信有些人可以修改它。:-) 这里的缺点是当没有弹出窗口阻止器时,弹出窗口会显示几秒钟(可能可以缩短一点)。

我把这个放在我的“主”窗口的部分中

<script type="text/JavaScript" language="JavaScript">

 var mine = window.open('popuptest.htm','popuptest','width=1px,height=1px,left=0,top=0,scrollbars=no');
 if(!mine|| mine.closed || typeof mine.closed=='undefined')
  {
    popUpsBlocked = true       
    alert('Popup blocker detected ');
    if(mine)
      mine.close();
 }
 else
 {
    popUpsBlocked = false    
    var cookieCheckTimer = null;
    cookieCheckTimer =  setTimeout('testPopup();', 3500);
 }


function testPopup()
{
  if(mine)
  {
    if(mine.test())
    {
       popUpsBlocked = false;
    }
    else
    {
        alert('Popup blocker detected ');
         popUpsBlocked = true;
     }
    mine.close();
}

} 
</script>

弹出测试看起来像这样:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" >
<head>
    <title>Popup test</title>
<script type="text/javascript" language="Javascript">
   function test() {if(window.innerHeight!=0){return true;} else return false;}
</script>
</head>

<body>
</body>
</html>

在弹出页上调用测试函数3500毫秒后,Chrome已正确设置内部高度。

我使用变量popUpsBlocked来确定其他JavaScript中是否显示弹出窗口。

function ShowConfirmationMessage()
{
if(popUpsBlocked)
 { 
  alert('Popups are blocked, can not display confirmation popup. A mail will be sent with the confirmation.');
 } 
 else
 { 
  displayConfirmationPopup();
 }
 mailConfirmation();
}

很不幸,这假设你要弹出的页面是由我们控制的。我需要打开一个我无法控制的外部页面。 - Roman

1

我也只能想到Jason的回答,但是依赖位置有点不可靠!

现在,你真的不需要问“我的未经请求的弹出窗口被阻止了吗?”,因为答案总是“是” - 所有主要浏览器默认都开启了弹出窗口拦截器。最好的方法是只在直接点击的响应中使用window.open(),这几乎总是允许的。


2
我知道最佳实践等,但我处于需要完成这项任务的情况下。这就是为什么我问这个问题而不是“我应该吗?” - Andrew Ensley

0
据我所知(从我的测试中),Chrome 返回一个位置为“about:blank”的窗口对象。 因此,以下内容适用于所有浏览器:
var newWin = window.open(url);
if(!newWin || newWin.closed || typeof newWin.closed=='undefined' || newWin.location=='about:blank')
{
    //POPUP BLOCKED
}

即使是未被阻止的弹出窗口,其位置仍将保持为“about:blank”。我在Chrome v28.0.1500.72上进行了测试。 - Roman

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接