Подтвердить что ты не робот

Блокировать всплывающее окно Bypass на window.open, когда установлен JQuery event.preventDefault()

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

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

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

Все работает отлично, только с блокировкой окна window.open блокируется всплывающее окно.

$('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 не блокирует страницу, однако для условия 1 он открывает диалог, а также открывает страницу "href".

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

Не могли бы вы помочь мне решить эту проблему?

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

4b9b3361

Ответ 1

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

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

  • Сделайте что-то еще, а не window.open.

  • Сделайте синхронный вызов 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, если вы можете найти любой другой способ достижения своей цели. Но если вы не можете, вы идете.

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

    Живой пример | Live source (прямые ссылки больше не работают из-за изменений в 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");
        });
      });
    });
    

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

    Живой пример | Live source (прямые ссылки больше не работают из-за изменений в 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");
          }
        });
      });
    });
    

Ответ 2

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

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

  • var myWindow = window.open('')
  • нарисовать любое загружаемое сообщение в этом окне
  • при выполнении запроса просто вызовите myWindow.location = 'http://google.com'

Ответ 3

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

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

Ответ 4

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

$('#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/

Ответ 5

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

Тем не менее, вы можете создать окно без 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 в основном работает нормально. Если вместо этого вы хотите отобразить загрузочное сообщение (или что-либо еще) в окне, пока пользователь ждет, вы можете использовать Data URI.

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

Ответ 6

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

$('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';

    });
});

Ответ 7

Попробуйте использовать элемент ссылку и щелкните по нему с помощью javascriipt

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

и script

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

Ответ 8

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

Вкратце: вам нужно вызвать window.open из события, инициированного пользователем, в этом случае щелкая по ссылке, и эта ссылка должна иметь 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');
});

Ответ 9

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

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

Ответ 10

Я использую этот метод, чтобы избежать блокировщика всплывающих окон в моем коде React. это будет работать во всех других кодах JavaScript также.

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

const popupWindow = window.open("", "_blank");
popupWindow.document.write("<div>Loading, Plesae wait...</div>")

при успешном выполнении асинхронного вызова напишите следующее

popupWindow.document.write(resonse.url)