检查窗口是否为弹出窗口?

37

这个问题不是if window is popup的重复,但是类似。

我正在开发一个扩展程序,它会向所有网页注入脚本。我需要检测窗口是否为弹出窗口。

注意: 我不是打开弹出窗口的人,所以上面的解决方案行不通。


你的弹出窗口是用window.open()实现的吗? - Govind Malviya
不,我不是打开弹出窗口的人。所以我与window.open()没有关系。 - Jeevan
你使用的是哪种类型的弹出窗口? - Govind Malviya
定义“弹出窗口”,因为浏览器有打开弹出窗口作为新标签页的选项。您是否认为“通过编程方式打开的标签页”也是弹出窗口? - Joseph
弹出窗口有一个父级“opener”,从另一个页面打开的页面(例如使用target=_blank)与原始窗口没有保持关系。 - Anthony
显示剩余4条评论
11个回答

40

我发现某些浏览器在某些情况下会将 window.opener 设置为 window。这是目前我正在使用的最可靠的弹出窗口检查。

if (window.opener && window.opener !== window) {
  // you are in a popup
}

是的,我觉得这个就是我们要找的。 - prograhammer
3
必须"这应该是被接受的答案"。 另外还有一个补充,如果您知道第二个参数中窗口的名称,可以使用以下代码:window.open('example.org','the-window-name'),可以通过if(window.opener && ... window.name === 'the-window-name')进行检查。 - Adrian Föder
3
如果您关闭“opener”浏览器窗口,则此方法无法正常工作。此时window.opener的值为null。当用户被重定向到另一个域时也会出现相同的情况(参考资料)。 - Christian Davén
1
这不是万能解决方案。正如一些评论中所指出的那样,即使窗口不是弹出窗口,如果使用window.open打开了窗口,甚至还有其他几种情况,window.opener也会返回true。请注意这一点。 - phillyslick
2
如果在检查之前打开程序窗口,它将无法工作,因为当父窗口关闭时,它被设置为 null。 - Brobic Vripiat
显示剩余4条评论

21

在测试Chrome、Firefox、Safari和IE8时,以下内容对我有效。无论是使用window.open()创建的窗口还是target=_blank方式打开的窗口都适用。

if (window.opener) {
    alert('inside a pop-up window or target=_blank window');
} else if (window.top !== window.self) {
    alert('inside an iframe');
} else {
    alert('this is a top level window');
}

如果弹出窗口具有另一个来源,则在IE中window.opener未定义。 - Joel
当弹出窗口包含一个iframe且检查window.opener的脚本在iframe内运行时,此方法将无法帮助解决问题。 - robert
3
我在普通页面中(非通过 window.open 弹出的弹窗)检测到 window.opener 的值为 true。我正在使用最新版的 Chrome。 - prograhammer
按F5刷新弹出窗口时无法工作。 - SwadhIn
如果打开器关闭了,它就无法工作。 - Brobic Vripiat

5

window.locationbar.visible 不一定只用于弹出窗口,但可以帮助检测用户是否可以通过地址栏手动更改位置...


最好查看window.menubar.visible,就像这个相关问题中所示。 - Christian Davén
为了一个Chrome扩展程序,我需要区分弹出窗口和在浏览器操作弹出窗口中加载的相同代码。我假设menubar.visible在两种情况下都是false,因为这两种类型的弹出窗口都不显示菜单栏。但实际上,在浏览器操作情况下它是true,因此可以用它来区分这两种扩展弹出窗口。 - jdunning

3
我使用这段代码来确定一个弹出窗口。
(window.opener && window.opener !== window && !window.menubar.visible)

2
window.opener && 这一部分是不必要的,因为如果 openernull,它就不等于 window - jdunning
2
window.opener && 位是必要的。否则,当 window.opener 为 null 时,它将不等于 window,并且它会认为它是一个弹出窗口,而实际上它不是。 - Ali Saeed
这在Safari中似乎不起作用。我发现即使在弹出窗口中,window.opener === window也是如此。 - rcbevans
rcbevans - 在弹出窗口中应该是 window.opener === window - Brobic Vripiat

2

我正在为弹出窗口屏幕实现“关闭”按钮,为“_self”窗口实现“取消”按钮,使用的是"Typescript/Nodejs",相信它也适用于JavaScript。因此,我需要确定屏幕是否在弹出窗口中打开。

最初的回答:

if(window.opener || window.history.length === 1) 
     isPopupWindow = true;
else 
   isPopupWindow = false;

"window.opener" 在大多数浏览器上都有效,但在IE上有问题,因此为了处理IE的问题,我使用了 "window.history.length"。

最初的回答:

使用 "window.history.length" 可以解决IE中 "window.opener" 的问题。


|| window.history.length === 1 将会在任何新打开的窗口上成立,无论它是弹出窗口还是不是。 - aljgom

2
if (window.menubar.visible) 
    // Not Popup
else
    // Popup

window.opener是一个布尔值,当一个窗口是弹出窗口时它的值为true,但仅在打开它的原始窗口仍然处于打开状态时才有效。如果原始窗口已关闭,则其值为false,因此它并不总是适用于确定一个窗口是否为弹出窗口。


2
如果窗口是弹出窗口或子框架,则以下语句将为真:
 window.parent != window

这对我来说都返回false,无论是弹出窗口还是通过普通的<a target="blank">打开的窗口,我认为OP没有检查。 - Anthony
我认为使用<a target="blank">不会创建弹出窗口。在我的理解中,弹出窗口是通过window.open()打开的。你用的是哪个浏览器?我已经在Chrome上尝试过了。 - Maksym Kozlenko
我知道它们不会创建弹出窗口。但是我想说的是,您的测试返回相同的结果,无论是通过“target”还是通过“window.open”打开的窗口。在Chrome浏览器上也是如此。 - Anthony
我需要检测窗口是否为弹出窗口。- 原始问题询问的是弹出窗口,而不是带有目标属性的超链接。 - Maksym Kozlenko
老兄,那正是我所说的。我的测试显示 window.parent != window 对于使用 window.open() 和通过 target="_blank" 打开的窗口/标签页返回相同的结果。因此,如果它是从 target="_blank" 打开的新窗口,则对于弹出窗口来说这将是一个误报,而这不是 OP 想要的。 - Anthony
2
让我们在聊天中继续这个讨论:http://chat.stackoverflow.com/rooms/10303/discussion-between-maksym-kozlenko-and-anthony - Maksym Kozlenko

1
为什么不直接检查打开者是否未定义?弹出窗口有一个打开者,而常规页面没有。
if (window.opener != null) 

1
你应该将 window.openernull 进行比较,而不是 undefined - Christian Davén
因为如果在检查打开器之前关闭打开器,打开器将变为空,因此不可靠。 - Brobic Vripiat

0

对我来说,我正在实现一个注销屏幕,可以通过window.open(..)在窗口弹出中显示,或者从单个页面内的链接中显示。

我需要确定:

1)如果我的注销屏幕在弹出窗口中,则:

event.preventDefault();
window.close();

2) 否则使用浏览器的返回功能。

window.history.back();

我的解决方案: 如果页面在弹出窗口中,在我的情况下,它有一个窗口页面历史记录为1:
event.preventDefault();
if (window.history.length === 1) {
    window.close();
} else {
    window.history.back();
}

-1

最好的方法是检查窗口宽度,然后尝试将窗口宽度调整一两个像素,然后检查当前宽度是否等于调整前的宽度。

换句话说,如果您成功调整了窗口大小,则可能在弹出窗口内。

祝你好运。


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