弹窗拦截API- 如何检查用户是否启用了它

25

当用户点击触发window.open的按钮时,我需要知道是否有稳定的API/方法在此之前了解用户是否主动使用弹出窗口拦截程序?

在某些情况下,用户并不知道/关注他们是否有弹出窗口拦截程序(阻止新窗口)。我想通过某个对话框或其他方式告诉他们点击“允许”以授权打开新窗口。

5个回答

37

Window.open(...) 如果存在新窗口,则返回一个句柄。如果它没有新窗口的句柄,则说明该窗口被阻止了。

https://developer.mozilla.org/en-US/docs/Web/API/Window/open

来源:https://davidwalsh.name/popup-block-javascript

var windowName = 'userConsole'; 
var popUp = window.open('/popup-page.php', windowName, 'width=1000, height=700, left=24, top=24, scrollbars, resizable');
if (popUp == null || typeof(popUp)=='undefined') {  
    alert('Please disable your pop-up blocker and click the "Open" link again.'); 
} 
else {  
    popUp.focus();
}

5
这是你的问题 - 我需要一种稳定的解决方案,以了解用户点击打开窗口事件时,如何知道他是否启用了弹出窗口拦截器。在窗口打开之前就要知道...谢谢!
我很抱歉,没有任何方法可以处理这个问题。我曾经研究过这个问题,现在分享一下我的发现。
为什么我们的弹出窗口会被阻止?
智能弹出窗口拦截器将允许与用户操作直接相关的弹出窗口。如果它有任何延迟,很可能会被阻止。
参考:Andy Stratton(他的博客)
我更喜欢这个解释。
一般规则是当从未被用户直接操作的javascript中调用window.open或类似方法时,弹出窗口拦截器会启动。也就是说,您可以在按钮单击的响应中调用window.open而不会受到弹出窗口拦截器的影响,但如果将相同的代码放入计时器事件中,则会被阻止。调用链的深度也是一个因素——一些旧版浏览器只查看直接调用者,而新版浏览器可以回溯一点,看看调用者的调用者是否是鼠标单击等。尽可能保持浅,以避免弹出窗口拦截器。
参考:dthorpe(Stack Overflow用户名)
我们能做什么?
目前清楚的一件事是,没有任何直接的方法可以从代码中调整弹出窗口拦截器。我认为背后的原因是这将破坏它存在的唯一理由。
您可以在Andy的博客上阅读他提出的解决方案:点击。简而言之,使用弹出窗口作为响应部分。Andy解释说,我们可以在用户操作后直接在响应部分使用windows.open,这样不会被弹出拦截器拦截。
正如xaxxon所解释的那样,在执行windows.open后检查它是否被阻止是可能的。通常人们会这样做,而开发人员在添加任何额外服务功能时也会考虑到这一点。例如,我正在实现Twitter的数字身份验证系统。我使用了检查弹出命令执行失败后的消息,然后我就可以向用户显示一条消息以启用弹出窗口,但后来我发现上述解决方案更加整洁和清晰。

顺便提一下,如果你想在打开窗口之前知道用户是否启用了弹出窗口拦截器,可以查看detectadblock,它可以给出一个大致的估计,判断用户是否运行广告拦截器。 - jake
@jake 广告拦截器场景会有帮助吗?我们正在讨论 windows.open - Gandalf the White
广告拦截器也有弹出窗口阻止功能,特别是对于像Firefox这样具有弱弹出窗口阻止器的浏览器。检测广告拦截器非常简单。 - jake

4

如果window.open()不是由点击事件触发,它大多数情况下会被阻止。

To confirm the window has loaded:

var loaded = false;

function windowLoaded() { 
  alert("The popup loaded"); 
  loaded = true
}

function pause(milliseconds) {
  var dt = new Date();
  while ((new Date()) - dt <= milliseconds) { /* Do nothing */ }
}

document.write("start...");

//open the window
var win = window.open("window.html");

// If window.open returned an object
if(win) {
  win.onload = function() { 
    win.RunCallbackFunction = windowLoaded; 
  };
  document.write("popup sent...");

  pause(3000);

  // Verify that out window loaded
  if (loaded == false)
    document.write("check you popup blocker!");
  else
    document.write("ok!");

}
else {
  document.write("window.open() was blocked...");
}


3
使用此代码来检查
var popupBlockerChecker = {check:function(b) {
var a = this;
b ? /chrome/.test(navigator.userAgent.toLowerCase()) ? setTimeout(function()      {
a._is_popup_blocked(a, b);
}, 200) : b.onload = function() {
a._is_popup_blocked(a, b);
} : a._displayError();
}, _is_popup_blocked:function(b, a) {
0 == 0 < a.innerHeight && b._displayError();
}, _displayError:function() {
alert("Popup Blocker is enabled! Please add this site to your exception list.");
}};

使用方式将会像这样:

 var popup = window.open("http://www.google.com.au", '_blank');
 popupBlockerChecker.check(popup);

2
以下是一个 jQuery 解决弹出窗口拦截器检查的方法。它已在火狐(v11)、Safari(v6)、Chrome(v23.0.127.95)和IE(v7和v9)中进行了测试。
var popupBlockerChecker = {
    check: function(popup_window){
        var _scope = this;
        if (popup_window) {
            if(/chrome/.test(navigator.userAgent.toLowerCase())){
                setTimeout(function () {
                    _scope._is_popup_blocked(_scope, popup_window);
                 },200);
            }else{
                popup_window.onload = function () {
                    _scope._is_popup_blocked(_scope, popup_window);
                };
            }
        }else{
            _scope._displayError();
        }
    },
    _is_popup_blocked: function(scope, popup_window){
        if ((popup_window.innerHeight > 0)==false){ scope._displayError(); }
    },
    _displayError: function(){
        alert("Popup Blocker is enabled! Please add this site to your exception list.");
    }
};

使用方法:

var popup = window.open("http://www.google.co.in", '_blank');
popupBlockerChecker.check(popup);

希望这能有所帮助。

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