Обход блокировщика всплывающих окон на окне.открыть при событии JQuery.метод preventDefault() устанавливается

Я хочу показать диалог JQuery условно на событии click гиперссылки .

у меня есть требование, как в condition1, откройте диалог JQuery, и если condition1 не удовлетворен, перейдите на страницу, на которую ссылается тег 'href', событие click которого находится под вопросом.

Я могу вызвать функцию на событие click по ссылке. Эта функция теперь проверяет указанное условие, выполняя другой URL (который выполняет мой контроллер Spring и возвращает ответ.)

все работает идеально, только с окном.открыть блокируется блокировщиком всплывающих окон.

$('a[href*=/viewpage?number]').live('click', function(e) {
    e.preventDefault();
    redirectionURL = this.href;
    pageId= getUrlVars(redirectionURL)["number"];
    $.getJSON("redirect/" + pageId, {}, function(status) {
        if (status == null) {
            alert("Error in verifying the status.");
        } else if(!status) {
            $("#agreement").dialog("open");
        } else {
            window.open(redirectionURL);
        }
    });
});

Если я удалить e.preventDefault(); из кода popoup blocker не блокирует страницу, однако для condition1 он затем открывает диалог, а также открывает страницу "href".

Если я решу один, это создаст проблему для другого. Я не могу отдать справедливость обоим условиям одновременно.

не могли бы вы помочь мне решить эту проблему пожалуйста?

после этого решена у меня есть еще одна проблема для решения, т. е. навигация по событию OK диалога:)

9 ответов


блокировщики всплывающих окон обычно разрешают только window.open если используется во время обработка события пользователя (например, щелчок). В вашем случае вы звоните window.open позже, а не во время мероприятия, потому что $.getJSON - это асинхронный.

у вас есть два варианта:

  1. сделайте что-нибудь другое, а не window.open.

  2. сделайте вызов ajax синхронным, чего обычно следует избегать, как чума, как он блокирует пользовательский интерфейс браузера. $.getJSON эквивалентно:

    $.ajax({
      url: url,
      dataType: 'json',
      data: data,
      success: callback
    });
    

    ...и поэтому вы можете сделать свой $.getJSON вызов синхронный, сопоставив ваши параметры выше и добавив async: false:

    $.ajax({
        url:      "redirect/" + pageId,
        async:    false,
        dataType: "json",
        data:     {},
        success:  function(status) {
            if (status == null) {
                alert("Error in verifying the status.");
            } else if(!status) {
                $("#agreement").dialog("open");
            } else {
                window.open(redirectionURL);
            }
        }
    });
    

    опять же, я не выступаю за синхронные вызовы ajax, если вы можете найти другой способ достичь своей цели. Но если вы не можете,вот так.

    вот пример кода, который не проходит тест из-за асинхронной звоните:

    видео | Живой источник (живые ссылки больше не работают из-за изменений в JSBin)

    jQuery(function($) {
      // This version doesn't work, because the window.open is
      // not during the event processing
      $("#theButton").click(function(e) {
        e.preventDefault();
        $.getJSON("http://jsbin.com/uriyip", function() {
          window.open("http://jsbin.com/ubiqev");
        });
      });
    });
    

    и вот пример, который работает, используя синхронный вызов:

    видео | Живой источник (живые ссылки больше не работают из-за изменений в JSBin)

    jQuery(function($) {
      // This version does work, because the window.open is
      // during the event processing. But it uses a synchronous
      // ajax call, locking up the browser UI while the call is
      // in progress.
      $("#theButton").click(function(e) {
        e.preventDefault();
        $.ajax({
          url:      "http://jsbin.com/uriyip",
          async:    false,
          dataType: "json",
          success:  function() {
            window.open("http://jsbin.com/ubiqev");
          }
        });
      });
    });
    

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

Итак, вы можете попробовать этот сценарий:

  1. var myWindow = окно.открыть (")
  2. нарисуйте любое сообщение загрузки в этом окне
  3. когда запрос сделан, просто позвоните myWindow.location ='http://google.com'

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

$scope.testCode = function () {
    var newWin = $window.open('', '_blank');
    service.testCode().then(function (data) {
        $scope.testing = true;
        newWin.location = '/Tests/' + data.url.replace(/["]/g, "");
    });
};

попробуйте это, это работает для меня,

$('#myButton').click(function () {
    var redirectWindow = window.open('http://google.com', '_blank');
    $.ajax({
        type: 'POST',
        url: '/echo/json/',
        success: function (data) {
            redirectWindow.location;
        }
    });
});

это скрипка для этого http://jsfiddle.net/safeeronline/70kdacL4/1/


Windows должна быть создана в одном стеке (aka microtask) как инициированное пользователем событие, например, обратный вызов щелчка--поэтому они не могут быть созданы позже, асинхронно.

вы можете создать окно без URL и вы можете изменить URL этого окна как только вы это узнаете, даже асинхронно!
window.onclick = () => {
  // You MUST create the window on the same event
  // tick/stack as the user-initiated event (e.g. click callback)
  const googleWindow = window.open();

  // Do your async work
  fakeAjax(response => {
    // Change the URL of the window you created once you
    // know what the full URL is!
    googleWindow.location.replace(`https://google.com?q=${response}`);
  });
};

function fakeAjax(callback) {
  setTimeout(() => {
    callback('example');
  }, 1000);
}

современные браузеры откроют окно с пустой страницей (часто называемой about:blank), и предполагая, что ваш асинхронный задача получить URL-адрес довольно быстро, полученный UX в основном в порядке. Если вместо этого вы хотите отобразить сообщение загрузки (или что-то еще) в окно, пока пользователь ждет, вы можете использовать Данные URIs.

window.open('data:text/html,<h1>Loading...<%2Fh1>');

этот код поможет мне. Надеюсь, это поможет некоторым людям

$('formSelector').submit( function( event ) {

    event.preventDefault();

    var newWindow = window.open('', '_blank', 'width=750,height=500');

    $.ajax({

        url: ajaxurl,
        type: "POST",
        data: { data },

    }).done( function( response ) {

        if ( ! response ) newWindow.close();
        else newWindow.location = '/url';

    });
});

использовать ссылка элемент и щелкните его с помощью javascriipt

<a id="SimulateOpenLink" href="#" target="_blank" rel="noopener noreferrer"></a>

и скрипт

function openURL(url) {
    document.getElementById("SimulateOpenLink").href = url
    document.getElementById("SimulateOpenLink").click()
}

используйте его так

//do stuff
var id = 123123141;
openURL("/api/user/" + id + "/print") //this open webpage bypassing pop-up blocker
openURL("https://www.google.com") //Another link

наблюдение за тем, что событие должно было быть инициировано пользователем, помогло мне понять первую часть этого, но даже после этого Chrome и Firefox все еще заблокировали новое окно. Вторая часть добавляла target= "_blank" к ссылке, которая была упомянута в одном комментарии.

in summary:вам нужно вызвать окно.открыть из события, инициированного Пользователем, в этом случае нажав на ссылку, и эта ссылка должна иметь target="_blank".

в примере ниже ссылка использует class= "button-twitter".

$('.button-twitter').click(function(e) {
  e.preventDefault();
  var href = $(this).attr('href');
  var tweet_popup = window.open(href, 'tweet_popup', 'width=500,height=300');
});

var url = window.open("", "_blank");
url.location = "url";

это сработало для меня.