Как запретить Google Chrome блокировать всплывающее окно?
На моем веб-сайте есть кнопка, которая просто использовалась для вызова функции, которая вызывает window.open
, однако в последнее время требуется настройка, чтобы выполнить проверку на стороне сервера до того, как всплывающее окно было открыто.
С момента добавления кода, который вызывает вызов AJAX, браузер блокирует всплывающее окно, которое открывается в обратном вызове success
вызова AJAX. Я читал, что браузеры могут блокировать всплывающее окно, если оно не вызвано событием клика пользователя, поэтому я попытался настроить запрос AJAX на async: false
, который решил проблему в Firefox, но Google Chrome по-прежнему блокирует всплывающее окно. Есть ли способ обойти это?
Я могу перенести проверку на стороне сервера на страницу, которая открывается во всплывающем окне, но я хотел бы сделать это, прежде чем открывать всплывающее окно, если это возможно.
код:
<a id="attackButton" href="#">Attack Base!</a>
<script type="text/javascript">
$(function() {
$('#attackButton').click(function() {
$.ajax({
url: baseurl + '/index.php?option=com_pbbgs&format=raw&getinfo=goingame',
data: { 'gameid': 618 },
dataType: 'text',
async: false,
type: 'POST',
success: function(data) {
eval(data);
if (window.gameURL) {
goingameRaw();
}
}
});
return false;
});
});
function goingameRaw()
{
window.open(window.gameURL,'test','left=20,top=20,width=1024,height=640,toolbar=0,resizable=0,location=0');
}
</script>
Пример тела ответа:
window.gameURL="http://mydomain.com/index.php?option=com_pbbgs&format=raw&startgame=618&width=1024&height=640";checktutorial('js','attack');
Ответы
Ответ 1
Да, всплывающие окна должны быть прямым результатом действия пользователя. Выполнение их в обратном вызове ajax не поможет. Кроме того, использование async:false
плохое - в FF известно, что он блокирует весь браузер. Подумайте о другом способе проверки:
- это может быть первое, что вы делаете во всплывающем меню
- вы можете открыть всплывающее окно щелчком и манипулировать им позже, когда обратный вызов срабатывает
- вы можете потребовать, чтобы пользователь снова нажал кнопку для запуска всплывающего окна (возможно, наихудшего решения)
- вы можете сделать это при загрузке страницы
Ответ 2
Следуя за превосходным ответом Эмиля, "вы можете открыть всплывающее окно щелчком и манипулировать им позже, когда срабатывает обратный вызов". Я использовал эту реализацию.
$('#attackButton').click(function() {
Новый код здесь
var win = window.open('');
window.oldOpen = window.open;
window.open = function(url) { // reassignment function
win.location = url;
window.open = oldOpen;
win.focus();
}
конец нового кода
$.ajax({
url: baseurl + '/index.php',
data: { 'gameid': 618 },
type: 'POST',
success: function(data) {
window.open('some url'); // will call reassignment function above
}
});
return false;
});
Ответ 3
Вы можете открыть окно, которое не заблокировано только при событии onclick, если вы откроете его при вызове ajax, это считается всплывающим. Однако я использовал этот метод с успехом в течение некоторого времени, чтобы открыть всплывающее окно и не блокироваться.
http://en.nisi.ro/blog/development/javascript/open-new-window-window-open-seen-chrome-popup/
Ответ 4
В моем случае window.open был запущен внутри обещания в angular, который включил блокировку всплывающих окон, мое решение было:
$scope.gotClick = function(){
var myNewTab = browserService.openNewTab();
someService.getUrl().then(
function(res){
browserService.updateLocation(res.url, myNewTab);
}
);
};
browserService:
this.openNewTab = function(){
var newTabWindow = $window.open();
return newTabWindow;
}
this.updateTabLocation = function(tabLocation, tab) {
if(!tabLocation){
tab.close();
}
tab.location.href = tabLocation;
}
так вы можете открыть новую вкладку с помощью ответа на обещание и не вызвать блокировщик всплывающих окон.
Ответ 5
Предыдущее решение не сработало для меня, но я основывался на нем и использовал именованное окно.
internalCounter++;
var tabbedWin = window.open('','windowName_'+internalCounter);
$.ajax({
url: url,
async: false,
indexValue:internalCounter,
success: function(){
var w= window.open(url, 'windowName_'+this.indexValue);
w.focus();
}
})
Ответ 6
Я использую этот метод:
- Перенаправление на ту же страницу с URL-адресом загрузки, добавленным как параметр:
window.location.href = window.location.protocol + '//' +
window.location.host + window.location.pathname +
"?download=" + encodeURIComponent(urlToDownload)
- Обнаружить этот параметр при инициализации и перенаправлении страницы для загрузки:
function param(name){
var results = new RegExp('[\\?&]' + name + '=([^&#]*)').exec(window.location.href);
if (!results) { return 0; }
return results[1] || 0;
}
var downloadParam = param('download');
if (downloadParam) {
window.location = decodeURIComponent(downloadParam);
}