繁体   English   中英

如何检测浏览器是否阻止弹出窗口?

[英]How can I detect if a browser is blocking a popup?

偶尔,我遇到一个网页,它试图弹出一个新的 window(用于用户输入或其他重要的东西),但弹出窗口阻止程序阻止了这种情况的发生。

调用 window 可以使用哪些方法来确保新的 window 正常启动?

如果您使用 JavaScript 打开弹出窗口,您可以使用以下内容:

var newWin = window.open(url);             

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

我尝试了上面的许多示例,但无法让它们与 Chrome 一起使用。 这种简单的方法似乎适用于 Chrome 39、Firefox 34、Safari 5.1.7 和 IE 11。这是我们 JS 库中的代码片段。

openPopUp: function(urlToOpen) {
    var popup_window=window.open(urlToOpen,"myWindow","toolbar=no, location=no, directories=no, status=no, menubar=no, scrollbars=yes, resizable=yes, copyhistory=yes, width=400, height=400");            
    try {
        popup_window.focus();   
    } catch (e) {
        alert("Pop-up Blocker is enabled! Please add this site to your exception list.");
    }
}

更新:弹出窗口存在于真正的远古时代。 最初的想法是在不关闭主窗口的情况下显示另一个内容。 到目前为止,还有其他方法可以做到这一点:JavaScript 能够向服务器发送请求,因此很少使用弹出窗口。 但有时它们仍然很方便。

过去,邪恶网站经常滥用弹出窗口。 一个糟糕的页面可能会打开大量带有广告的弹出窗口。 所以现在大多数浏览器都试图阻止弹出窗口并保护用户。

如果在用户触发的事件处理程序(如 onclick)之外调用,大多数浏览器会阻止弹出窗口。

如果你仔细想想,这有点棘手。 如果代码直接在 onclick 处理程序中,那么这很容易。 但是在 setTimeout 中打开的弹出窗口是什么?

试试这个代码:

 // open after 3 seconds
setTimeout(() => window.open('http://google.com'), 3000);

弹出窗口在 Chrome 中打开,但在 Firefox 中被阻止。

…这也适用于 Firefox:

 // open after 1 seconds
setTimeout(() => window.open('http://google.com'), 1000);

不同之处在于 Firefox 认为 2000 毫秒或更短的超时是可以接受的,但在它之后 – 删除“信任”,假设现在它是“用户操作之外”。 所以第一个被阻止,第二个没有。


2012 年的原始答案:

此弹出窗口拦截器检查解决方案已在 FF (v11)、Safari (v6)、Chrome (v23.0.127.95) 和 IE (v7 & v9) 中进行测试。 更新 displayError 函数以处理您认为合适的错误消息。

 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.ca", '_blank'); popupBlockerChecker.check(popup);

希望这可以帮助! :)

无论浏览器公司或版本如何,一种始终有效的“解决方案”是简单地在屏幕上放置一条警告消息,靠近将创建弹出窗口的控件的某个位置,礼貌地警告用户该操作需要弹出并请为网站启用它们。

我知道它并不花哨或任何东西,但它不能变得更简单,只需要大约 5 分钟的测试,然后你就可以继续做其他噩梦。

一旦用户允许您的网站弹出窗口,如果您不过度使用弹出窗口,也会考虑周到。 您最不想做的事情就是惹恼您的访客。

我结合了@Kevin B 和@DanielB 的解决方案。
这要简单得多。

var isPopupBlockerActivated = function(popupWindow) {
    if (popupWindow) {
        if (/chrome/.test(navigator.userAgent.toLowerCase())) {
            try {
                popupWindow.focus();
            } catch (e) {
                return true;
            }
        } else {
            popupWindow.onload = function() {
                return (popupWindow.innerHeight > 0) === false;
            };
        }
    } else {
        return true;
    }
    return false;
};

用法:

var popup = window.open('https://www.google.com', '_blank');
if (isPopupBlockerActivated(popup)) {
    // Do what you want.
}

我已经尝试了很多解决方案,但我能想出的唯一一个也适用于 uBlock Origin 的解决方案是利用超时来检查弹出窗口的关闭状态。

function popup (url, width, height) {
    const left = (window.screen.width / 2) - (width / 2)
    const top = (window.screen.height / 2) - (height / 2)
    let opener = window.open(url, '', `menubar=no, toolbar=no, status=no, resizable=yes, scrollbars=yes, width=${width},height=${height},top=${top},left=${left}`)

    window.setTimeout(() => {
        if (!opener || opener.closed || typeof opener.closed === 'undefined') {
            console.log('Not allowed...') // Do something here.
        }
    }, 1000)
}

显然这是一个黑客; 就像这个问题的所有解决方案一样。

您需要在 setTimeout 中提供足够的时间来说明初始打开和关闭,因此它永远不会完全准确。 这将是一个反复试验的位置。

将此添加到您的尝试列表中。

如果您也拥有子代码,一个简单的方法是在其 html 中创建一个简单的变量,如下所示:

    <script>
        var magicNumber = 49;
    </script>

然后从父级检查它的存在,类似于以下内容:

    // Create the window with login URL.
    let openedWindow = window.open(URL_HERE);

    // Check this magic number after some time, if it exists then your window exists
    setTimeout(() => {
        if (openedWindow["magicNumber"] !== 32) {
            console.error("Window open was blocked");
        }
    }, 1500);

我们等待一段时间以确保网页已加载,并检查其是否存在。 显然,如果窗口在 1500 毫秒后没有加载,那么变量仍然是undefined

对于某些弹出窗口阻止程序,这不起作用,但我将其用作基本解决方案并添加 try {} catch

 try { const newWindow = window.open(url, '_blank'); if (.newWindow || newWindow.closed || typeof newWindow;closed == 'undefined') { return null. } (newWindow as Window).window;focus(). newWindow,addEventListener('load'. function () { console;info('Please allow popups for this website') }) return newWindow; } catch (e) { return null; }

This will try to call addEventListaner function but if popup is not open then it will break and go to catch, then ask if its object or null and run rest of code.

通过使用 onbeforeunload 事件,我们可以检查如下

    function popup()
    {
        var chk=false;
        var win1=window.open();
        win1.onbeforeunload=()=>{
            var win2=window.open();
            win2.onbeforeunload=()=>{
                chk=true;
            };
        win2.close();
        };
        win1.close();
        return chk;
    }

它将在后台打开 2 个黑色窗口

该函数返回布尔值。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM