小编典典

检测Chrome中阻止的弹出窗口

javascript

我知道可以检测其他浏览器是否阻止了弹出窗口的javascript技术。这是基本测试:

var newWin = window.open(url);

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

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

当然,该测试在一定程度上是可行的,因为Chrome实际上并没有阻止弹出窗口,而是在右下角的最小化最小窗口中打开了该窗口,其中列出了“阻止的”弹出窗口。

我想做的就是能够确定弹出窗口是否被Chrome的弹出窗口阻止程序阻止了。我尝试避免浏览器对功能检测的嗅探。有没有办法做到这一点而无需浏览器嗅探?

编辑
:我现在已经尝试过利用的newWin.outerHeightnewWin.left以及其他类似性质的做到这一点。弹出窗口被阻止时,Google
Chrome会将所有位置和高度值返回为0。

不幸的是,即使实际打开了未知时间的弹出窗口,它也会返回相同的值。经过一段神奇的时期(在我的测试中是几秒钟),位置和大小信息将作为正确的值返回。换句话说,我离解决这个问题还差得远。任何帮助,将不胜感激。


阅读 601

收藏
2020-05-01

共1个答案

小编典典

好吧,您所说的“魔术时间”可能是当弹出窗口的DOM已加载时。否则可能是当所有内容(图像,舷外CSS等)均已加载时。您可以通过在弹出窗口中添加非常大的图形来轻松测试(首先清除缓存!)。如果您使用的是jQuery之类的Javascript框架(或类似的东西),则可以使用ready()事件(或类似的东西)来等待DOM加载,然后再检查窗口偏移。这样做的危险在于Safari检测的工作方式相互矛盾:弹出窗口的DOM在Safari中永远不会ready(),因为它将为您要打开的窗口提供有效的句柄-无论它实际上是打开的还是打开的不。(实际上,我相信您上面的弹出式测试代码不适用于野生动物园。)

我认为您可以做的最好的事情是将测试包装在setTimeout()中,并在运行测试之前给弹出窗口3-5秒以完成加载。它不是完美的,但它至少应在95%的时间内正常工作。

这是我用于跨浏览器检测的代码,没有Chrome部件。

function _hasPopupBlocker(poppedWindow) {
    var result = false;

    try {
        if (typeof poppedWindow == 'undefined') {
            // Safari with popup blocker... leaves the popup window handle undefined
            result = true;
        }
        else if (poppedWindow && poppedWindow.closed) {
            // This happens if the user opens and closes the client window...
            // Confusing because the handle is still available, but it's in a "closed" state.
            // We're not saying that the window is not being blocked, we're just saying
            // that the window has been closed before the test could be run.
            result = false;
        }
        else if (poppedWindow && poppedWindow.test) {
            // This is the actual test. The client window should be fine.
            result = false;
        }
        else {
            // Else we'll assume the window is not OK
            result = true;
        }

    } catch (err) {
        //if (console) {
        //    console.warn("Could not access popup window", err);
        //}
    }

    return result;
}

我要做的是从父级运行此测试,并将其包装在setTimeout()中,从而使子窗口加载3-5秒。在子窗口中,您需要添加一个测试功能:

功能测试() {}

弹出窗口阻止程序检测器进行测试,以查看“ test”功能是否作为子窗口的成员存在。

2015年6月15日新增:

我认为处理此问题的现代方法是使用window.postMessage()来让孩子通知父窗口已经加载。这种方法是相似的(孩子告诉父母它已经加载了),但是通信方式已经得到了改善。我可以从孩子那里进行跨域操作:

$(window).load(function() {
  this.opener.postMessage({'loaded': true}, "*");
  this.close();
});

父母使用以下方式收听此消息:

$(window).on('message', function(event) {     
  alert(event.originalEvent.data.loaded)
});

希望这可以帮助。

2020-05-01