当设置了 JQuery event.proventDefault()时,绕过 window.open 上的弹出窗口阻塞器

我想在超链接的单击事件上有条件地显示一个 JQuery 对话框。

我有一个需求,比如 on 條 tion1打开一个 JQuery 对话框,如果條 tion1没有得到满足,导航到被其 click 事件的‘ href’标签引用的页面。

我能够调用一个函数的链接的点击事件。此函数现在通过执行另一个 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();,弹出窗口阻止程序不会阻止页面,但是对条件1,它会打开对话框并打开“ href”页面。

如果我解决了一个问题,就会给另一个问题制造麻烦,我无法同时公正地对待这两个问题。

你能帮我解决这个问题吗?

一旦这个问题解决了,我还有另一个问题需要解决,比如对话中 OK 事件的导航

180123 次浏览

Popup blockers will typically only allow window.open if used during the processing of a user event (like a click). In your case, you're calling window.open later, not during the event, because $.getJSON is asynchronous.

You have two options:

  1. Do something else, rather than window.open.

  2. Make the ajax call synchronous, which is something you should normally avoid like the plague as it locks up the UI of the browser. $.getJSON is equivalent to:

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

    ...and so you can make your $.getJSON call synchronous by mapping your params to the above and adding 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);
    }
    }
    });
    

    Again, I don't advocate synchronous ajax calls if you can find any other way to achieve your goal. But if you can't, there you go.

    Here's an example of code that fails the test because of the asynchronous call:

    Live example | Live source (The live links no longer work because of changes to 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");
    });
    });
    });
    

    And here's an example that does work, using a synchronous call:

    Live example | Live source (The live links no longer work because of changes to 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");
    }
    });
    });
    });
    

you can call window.open without browser blocking only if user does directly some action. Browser send some flag and determine that window opened by user action.

So, you can try this scenario:

  1. var myWindow = window.open('')
  2. draw any loading message in this window
  3. when request done, just call myWindow.location = 'http://google.com'

The observation that the event had to be initiated by the user helped me to figure out the first part of this, but even after that Chrome and Firefox still blocked the new window. The second part was adding target="_blank" to the link, which was mentioned in one comment.

In summary: you need to call window.open from an event initiated by the user, in this case clicking on a link, and that link needs to have target="_blank".

In the example below the link is using 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');
});

try this, it works for me,

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

Is fiddle for this http://jsfiddle.net/safeeronline/70kdacL4/1/

I had this problem and I didn't have my url ready untill the callback would return some data. The solution was to open blank window before starting the callback and then just set the location when the callback returns.

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

Windows must be created on the same stack (aka microtask) as the user-initiated event, e.g. a click callback--so they can't be created later, asynchronously.

However, you can create a window without a URL and you can then change that window's URL once you do know it, even asynchronously!

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);
}

Modern browsers will open the window with a blank page (often called about:blank), and assuming your async task to get the URL is fairly quick, the resulting UX is mostly fine. If you instead want to render a loading message (or anything) into the window while the user waits, you can use Data URIs.

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

This code help me. Hope this help some people

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


});
});

Try using an a link element and click it with javascriipt

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

and the script

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

Use it like this

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

this worked for me.

I am using this method to avoid the popup blocker in my React code. it will work in all other javascript codes also.

When you are making an async call on click event, just open a blank window first and then write the URL in that later when an async call will complete.

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

on async call's success, write the following

popupWindow.document.write(resonse.url)