Javascript 检测Chrome中被阻止的弹出窗口
我知道javascript技术可以检测弹出窗口是否在其他浏览器中被阻止(如中所述)。以下是基本测试:Javascript 检测Chrome中被阻止的弹出窗口,javascript,google-chrome,popup,Javascript,Google Chrome,Popup,我知道javascript技术可以检测弹出窗口是否在其他浏览器中被阻止(如中所述)。以下是基本测试: var newWin = window.open(url); if(!newWin || newWin.closed || typeof newWin.closed=='undefined') { //POPUP BLOCKED } 但这在Chrome中不起作用。当弹出窗口被阻止时,永远不会到达“弹出窗口被阻止”部分 当然,这个测试在一定程度上是有效的,因为Chrome实际上并没有阻
var newWin = window.open(url);
if(!newWin || newWin.closed || typeof newWin.closed=='undefined')
{
//POPUP BLOCKED
}
但这在Chrome中不起作用。当弹出窗口被阻止时,永远不会到达“弹出窗口被阻止”部分
当然,这个测试在一定程度上是有效的,因为Chrome实际上并没有阻止弹出窗口,而是在右下角的一个最小化窗口中打开它,该窗口列出了“被阻止的”弹出窗口
我想做的是能够告诉如果弹出被铬的弹出阻止。我尽量避免浏览器嗅探,而支持特征检测。有没有一种不用浏览器嗅探就能做到这一点的方法
编辑:我现在尝试使用newWin.outerHeight
、newWin.left
,以及其他类似的属性来完成此操作。当弹出窗口被阻止时,Google Chrome将所有位置和高度值返回为0
不幸的是,即使弹出窗口实际打开的时间未知,它也会返回相同的值。经过一段神奇的时间(在我的测试中几秒钟),位置和大小信息将作为正确的值返回。换言之,我还没有弄清楚这一点。任何帮助都将不胜感激。检查窗口相对于父窗口的位置。Chrome使窗口几乎脱离屏幕。杰森的回答也是我能想到的唯一方法,但依赖这样的位置有点不可靠 现在,你真的不需要问“我的主动弹出被阻止了吗?”这个问题,因为答案总是“是” — 默认情况下,所有主要浏览器都打开了弹出窗口阻止程序。最好的方法是直接点击window.open(),这几乎总是允许的。您所说的“神奇时刻”可能是在加载弹出窗口的DOM时。或者,它可能是当所有东西(图像、外部CSS等)都已加载时。您可以通过在弹出窗口中添加一个非常大的图形(首先清除缓存!)来轻松测试这一点。如果使用jQuery(或类似的东西)之类的Javascript框架,那么可以使用ready()事件(或类似的东西)在检查窗口偏移量之前等待DOM加载。这样做的危险在于Safari检测的工作方式相互冲突:弹出窗口的DOM在Safari中永远不会就绪(),因为它会为您试图打开的窗口提供一个有效的句柄——不管它是否实际打开。(事实上,我相信上面的弹出测试代码对safari不起作用。) 我认为您可以做的最好的事情是在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秒的加载时间。在子窗口中,您需要添加一个测试函数:
函数测试(){}
弹出式拦截器检测器测试“测试”功能是否作为子窗口的成员存在
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)
});
希望这有帮助。嗨
我稍微修改了上面描述的解决方案,认为它至少适用于Chrome。
我的解决方案是在主页打开时检测弹出窗口是否被阻止,而不是在弹出窗口打开时,但我确信有人可以修改它。:-)
这里的缺点是,当没有弹出窗口阻止程序时,弹出窗口会显示几秒钟(可能会缩短一点)
我把这个放在“主”窗口的部分
<script type="text/JavaScript" language="JavaScript">
var mine = window.open('popuptest.htm','popuptest','width=1px,height=1px,left=0,top=0,scrollbars=no');
if(!mine|| mine.closed || typeof mine.closed=='undefined')
{
popUpsBlocked = true
alert('Popup blocker detected ');
if(mine)
mine.close();
}
else
{
popUpsBlocked = false
var cookieCheckTimer = null;
cookieCheckTimer = setTimeout('testPopup();', 3500);
}
function testPopup()
{
if(mine)
{
if(mine.test())
{
popUpsBlocked = false;
}
else
{
alert('Popup blocker detected ');
popUpsBlocked = true;
}
mine.close();
}
}
</script>
我有一个类似的问题,弹出窗口不能在Chrome中打开。我很沮丧,因为我没有尝试做一些鬼鬼祟祟的事情,比如一个加载弹出窗口,只是在用户点击时打开一个窗口。我倍感沮丧,因为从firebug命令行运行包括window.open()在内的函数是有效的,而实际上单击我的链接却没有!以下是我的解决方案: 错误的方法:从事件侦听器运行window.open()(在我的示例中,dojo.connect连接到DOM节点的onclick事件方法) 正确方法:将函数分配给调用window.open()的节点的onclick属性 当然,如果需要,我仍然可以为同一个onclick事件创建事件侦听器。有了这个改变,我可以打开我的窗口,即使Chrome设置为“不允许任何网站显示弹出窗口”。乔伊 如果任何对Chrome有了解的人都能告诉我们为什么它会起作用,我很乐意听到,尽管我怀疑这只是试图关闭恶意编程弹出窗口的大门。据我所知(根据我的测试),Chrome返回一个位置为“about:blank”的窗口对象。 因此,以下内容适用于所有浏览器:
var newWin = window.open(url);
if(!newWin || newWin.closed || typeof newWin.closed=='undefined' || newWin.location=='about:blank')
{
//POPUP BLOCKED
}
这是一个目前正在使用Chrome的版本。只是对Rich的解决方案做了一个小小的改动,不过我也添加了一个处理计时的包装器
function checkPopupBlocked(poppedWindow) {
setTimeout(function(){doCheckPopupBlocked(poppedWindow);}, 5000);
}
function doCheckPopupBlocked(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.outerWidth == 0) {
// This is usually Chrome's doing. The outerWidth (and most other size/location info)
// will be left at 0, EVEN THOUGH the contents of the popup will exist (including the
// test function we check for next). The outerWidth starts as 0, so a sufficient delay
// after attempting to pop is needed.
result = true;
}
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);
//}
}
if(result)
alert("The popup was blocked. You must allow popups to use this site.");
}
要使用它,请执行以下操作:
var popup=window.open('location',etc...);
checkPopupBlocked(popup);
如果弹出get被阻止,警报消息将在5秒宽限期后显示(您可以调整,但5秒应该是非常安全的)。此片段包含上述所有内容-出于某种原因-StackOverflow排除了下面代码块中的第一行和最后一行代码,因此我写了一篇博客。有关完整的解释和其他(可下载)代码,请参阅
里奇的答案根本不起作用
myNode.onclick = function() {
window.open();
}
var newWin = window.open(url);
if(!newWin || newWin.closed || typeof newWin.closed=='undefined' || newWin.location=='about:blank')
{
//POPUP BLOCKED
}
function checkPopupBlocked(poppedWindow) {
setTimeout(function(){doCheckPopupBlocked(poppedWindow);}, 5000);
}
function doCheckPopupBlocked(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.outerWidth == 0) {
// This is usually Chrome's doing. The outerWidth (and most other size/location info)
// will be left at 0, EVEN THOUGH the contents of the popup will exist (including the
// test function we check for next). The outerWidth starts as 0, so a sufficient delay
// after attempting to pop is needed.
result = true;
}
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);
//}
}
if(result)
alert("The popup was blocked. You must allow popups to use this site.");
}
var popup=window.open('location',etc...);
checkPopupBlocked(popup);
var PopupWarning = {
init : function()
{
if(this.popups_are_disabled() == true)
{
this.redirect_to_instruction_page();
}
},
redirect_to_instruction_page : function()
{
document.location.href = "http://thecodeabode.blogspot.com";
},
popups_are_disabled : function()
{
var popup = window.open("http://localhost/popup_with_chrome_js.html", "popup_tester", "width=1,height=1,left=0,top=0");
if(!popup || popup.closed || typeof popup == 'undefined' || typeof popup.closed=='undefined')
{
return true;
}
window.focus();
popup.blur();
//
// Chrome popup detection requires that the popup validates itself - so we need to give
// the popup time to load, then call js on the popup itself
//
if(navigator && (navigator.userAgent.toLowerCase()).indexOf("chrome") > -1)
{
var on_load_test = function(){PopupWarning.test_chrome_popups(popup);};
var timer = setTimeout(on_load_test, 60);
return;
}
popup.close();
return false;
},
test_chrome_popups : function(popup)
{
if(popup && popup.chrome_popups_permitted && popup.chrome_popups_permitted() == true)
{
popup.close();
return true;
}
//
// If the popup js fails - popups are blocked
//
this.redirect_to_instruction_page();
}
};
PopupWarning.init();
var myPopup = window.open("site-on-my-domain", "screenX=100");
if (!myPopup)
alert("failed for most browsers");
else {
myPopup.onload = function() {
setTimeout(function() {
if (myPopup.screenX === 0)
alert("failed for chrome");
}, 0);
};
}
var myPopup = window.open("popupcheck.htm", "", "directories=no,height=150,width=150,menubar=no,resizable=no,scrollbars=no,status=no,titlebar=no,top=0,location=no");
if (!myPopup)
alert("failed for most browsers");
else {
myPopup.onload = function() {
setTimeout(function() {
if (myPopup.screenX === 0) {
alert("failed for chrome");
} else {
// close the test window if popups are allowed.
myPopup.close();
}
}, 0);
};
}
function openPopUpWindow(format)
{
var win = window.open('popupShow.html',
'ReportViewer',
'width=920px,height=720px,left=50px,top=20px,location=no,directories=no,status=no,menubar=no,toolbar=no,resizable=1,maximize:yes,scrollbars=0');
if (win == null || typeof(win) == "undefined" || (win == null && win.outerWidth == 0) || (win != null && win.outerHeight == 0) || win.test == "undefined")
{
alert("The popup was blocked. You must allow popups to use this site.");
}
else if (win)
{
win.onload = function()
{
if (win.screenX === 0) {
alert("The popup was blocked. You must allow popups to use this site.");
win.close();
}
};
}
}
cope.PopupTest.params = 'height=1,width=1,left=-100,top=-100,location=no,toolbar=no,menubar=no,scrollbars=no,resizable=no,directories=no,status=no';
cope.PopupTest.testWindow = window.open("popupTest.htm", "popupTest", cope.PopupTest.params);
if( !cope.PopupTest.testWindow
|| cope.PopupTest.testWindow.closed
|| (typeof cope.PopupTest.testWindow.closed=='undefined')
|| cope.PopupTest.testWindow.outerHeight == 0
|| cope.PopupTest.testWindow.outerWidth == 0
) {
// pop-ups ARE blocked
document.location.href = 'popupsBlocked.htm';
}
else {
// pop-ups are NOT blocked
cope.PopupTest.testWindow.close();
}
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);
window.isPopupBlocked = function(popup_window, cb)
{
var CHROME_CHECK_TIME = 2000; // the only way to detect this in Chrome is to wait a bit and see if the window is present
function _is_popup_blocked(popup)
{
return !popup.innerHeight;
}
if (popup_window) {
if (popup_window.closed) {
// opened OK but was closed before we checked
cb(false);
return;
}
if (/chrome/.test(navigator.userAgent.toLowerCase())) {
// wait a bit before testing the popup in chrome
setTimeout(function() {
cb(_is_popup_blocked(popup_window));
}, CHROME_CHECK_TIME);
} else {
// for other browsers, add an onload event and check after that
popup_window.onload = function() {
cb(_is_popup_blocked(popup_window));
};
}
} else {
cb(true);
}
};
function popup(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.");
}
}
const openPopUp = (...args) => new Promise(s => {
const win = window.open(...args)
if (!win || win.closed) return s()
setTimeout(() => (win.innerHeight > 0 && !win.closed) ? s(win) : s(), 200)
})
const win = await openPopUp('popuptest.htm', 'popuptest')
if (!win) {
// popup closed or blocked, handle alternative case
}