145

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

调用窗口可以使用哪些方法来确保新窗口正确启动?

4

8 回答 8

182

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

var newWin = window.open(url);             

if(!newWin || newWin.closed || typeof newWin.closed=='undefined') 
{ 
    //POPUP BLOCKED
}
于 2008-08-05T22:03:27.953 回答
47

我尝试了上面的一些示例,但无法让它们与 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.");
    }
}
于 2014-12-31T19:16:29.847 回答
35

更新:弹出窗口存在于非常古老的时代。最初的想法是在不关闭主窗口的情况下显示另一个内容。到目前为止,还有其他方法可以做到这一点: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);

希望这可以帮助!:)

于 2012-11-30T20:39:57.453 回答
14

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

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

一旦用户允许您的网站弹出窗口,如果您不过度使用弹出窗口也是体贴的。您要做的最后一件事就是惹恼您的访客。

于 2016-02-26T22:49:35.260 回答
1

我结合了@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.
}
于 2019-02-27T05:53:13.450 回答
0

我尝试了很多解决方案,但我能想到的唯一一个也适用于 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)
}

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

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

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

于 2018-01-30T12:29:01.120 回答
0

如果您也拥有子代码,一种简单的方法是在其 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.

于 2020-01-31T06:52:17.363 回答
-1

通过使用 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 个黑色窗口

该函数返回布尔值。

于 2018-05-29T14:56:56.983 回答