Javascript window.open из callback

window.open(), вызываемый из основного потока, открывает по умолчанию новую вкладку.

Но здесь каждый раз открывайте новое окно (Opera 16 и Google Chrome 29)

<input type="button" value="Open" onclick="cb1()">

<script type="text/javascript">  
function cb1() {
    setTimeout(wo, 1000); //simple async
}

function wo()
{
   var a = window.open("http://google.com", "w2");
   a.focus();
}
</script>

(lol, это мой ответ для Откройте URL-адрес на новой вкладке (а не в новом окне) с помощью JavaScript).

Как я могу открыть вкладку (по умолчанию браузера)?

Ответ 1

Мы столкнулись с этой проблемой и охотились вокруг SO за ответ. То, что мы нашли, работает в наших условиях, и дистиллированная мудрость такова:

Проблема связана с блокировщиками всплывающих окон браузера, предотвращающими открытие программных окон. Браузеры позволяют открывать окно с фактических кликов пользователей, которые происходят в основном потоке. Аналогично, если вы вызовеете window.open в основном потоке, он будет работать, как указано выше. В соответствии с этим ответом на Откройте URL-адрес на новой вкладке (а не в новом окне) с использованием JavaScript, если вы используете вызов Ajax и хотите открыть окно успеха вам нужно установить async: false, который работает, потому что он будет содержать все в основном потоке.

Мы не могли контролировать наш вызов Ajax, как это, но нашли другое решение, которое работает по тем же причинам. Предупреждение, это немного взломанно и может не соответствовать вам, учитывая ваши ограничения. Предоставлено замечание о другом ответе на Откройте URL-адрес на новой вкладке (а не в новом окне) с помощью JavaScript, вы откроете окно перед вызовом setTimeout, а затем обновите его в функции с задержкой. Есть несколько способов сделать это. Либо сохраняйте ссылку на окно при его открытии, w = window.open... и установите w.location, либо откройте цель, window.open('', 'target_name'), в задержанной функции, открытой в этой цели, window.open('your-url', 'target_name') и полагайтесь на браузер, поддерживая ссылка.

Конечно, если у пользователя есть свои настройки для открытия ссылок в новом окне, это не изменит его, но это не проблема для OP.

Ответ 2

Если новое окно открывается как новая вкладка или новый экземпляр, это зависит от настроек пользователя.

Ответ 3

Как и в других статьях, упоминается, что лучший способ сделать это - сначала открыть окно, а затем установить его местоположение после обратного вызова или асинхронной функции.

<input type="button" value="Open" onclick="cb1()">

<script type="text/javascript">

function cb1() {
  var w = window.open('', 'w2');
  setTimeout(function () {
    wo(w);
  }, 1000); //simple async
}

function wo(w)
{
  w.location = "http://google.com";
  w.focus();
}
</script>

В качестве альтернативы, если вы используете async await, которая также будет иметь ту же проблему, вы все равно можете использовать эту технику.

public async openWindow(): Promise<void> {
    const w = window.open('', '_blank');
    const url = await getUrlAsync();
    w.location = url;    
}

Еще одним улучшением является открытие окна на начальной странице, которое обеспечивает быструю обратную связь либо путем загрузки URL-адреса, либо написания HTML-кода на эту страницу.

public async openWindow(): Promise<void> {
    const w = window.open('', '_blank');
    w.document.write("<html><head></head><body>Please wait while we redirect you</body></html>");
    w.document.close();
    const url = await getUrlAsync();
    w.location = url;    
}

Это не позволит пользователю просматривать пустую вкладку/окно, сколько бы времени ни заняло разрешение вашего URL.