Ignora il blocco popup su window.open quando viene impostato JQuery event.preventDefault ()

Voglio mostrare una finestra di dialogo JQuery condizionalmente all’evento click di un collegamento ipertestuale.

Ho un requisito come on condition1 aprire un dialogo JQuery e se condition1 non è soddisfatto, navigare alla pagina come indicato dal tag ‘href’ del cui evento click è in questione.

Sono in grado di chiamare una funzione sull’evento click del collegamento. Questa funzione ora verifica la condizione specificata eseguendo un altro URL (che esegue il mio controller Spring e restituisce la risposta).

Tutto funziona perfettamente con solo window.open che viene bloccato dal blocco popup.

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

Se rimuovo e.preventDefault(); dal codice, popoup blocker non blocca la pagina, tuttavia per condizione1 apre quindi il dialogo e apre la pagina ‘href’.

Se risolvo uno, crea un problema per un altro. Non sono in grado di rendere giustizia a entrambe le condizioni contemporaneamente.

Potresti aiutarmi a risolvere questo problema per favore?

Una volta risolto, ho un altro problema da risolvere, ad esempio la navigazione sull’evento OK del dialogo 🙂

I blocchi popup in genere consentono solo window.open se utilizzati durante l’elaborazione di un evento utente (come un clic). Nel tuo caso, stai chiamando window.open più tardi , non durante l’evento, perché $.getJSON è asincrono.

Hai due opzioni:

  1. Fai qualcos’altro, piuttosto che window.open .

  2. Rendi sincrona la chiamata ajax, che normalmente dovresti evitare come la piaga mentre blocca l’interfaccia utente del browser. $.getJSON è equivalente a:

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

    … e così puoi rendere sincrona la tua chiamata $.getJSON mappando i tuoi param su quanto sopra e aggiungendo 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); } } }); 

    Ancora una volta, non sostengo le chiamate sincrone ajax se riesci a trovare un altro modo per raggiungere il tuo objective. Ma se non puoi, eccoti.

    Ecco un esempio di codice che fallisce il test a causa della chiamata asincrona:

    Esempio dal vivo | Fonte live (i collegamenti live non funzionano più a causa di modifiche a 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"); }); }); }); 

    Ed ecco un esempio che funziona, usando una chiamata sincrona:

    Esempio dal vivo | Fonte live (i collegamenti live non funzionano più a causa di modifiche a 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"); } }); }); }); 

puoi chiamare window.open senza bloccare il browser solo se l’utente fa direttamente qualche azione. Il browser invia un flag e determina la finestra aperta dall’azione dell’utente.

Quindi, puoi provare questo scenario:

  1. var myWindow = window.open (”)
  2. disegnare qualsiasi messaggio di caricamento in questa finestra
  3. quando la richiesta viene eseguita, chiama myWindow.location = ‘ http://google.com

Ho avuto questo problema e non ho avuto il mio URL pronto fino alla richiamata restituire alcuni dati. La soluzione era di aprire una finestra vuota prima di avviare la richiamata e quindi di impostare la posizione quando il callback ritorna.

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

prova questo, funziona per me,

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

È fiddle per questo http://jsfiddle.net/safeeronline/70kdacL4/1/

Windows deve essere creato nello stesso stack (ovvero microtask ) come evento avviato dall’utente, ad esempio un richiamo di clic, in modo che non possano essere creati in seguito, in modo asincrono.

Tuttavia, puoi creare una finestra senza un URL e puoi modificare l’URL di quella finestra una volta che lo conosci , anche in modo asincrono!

 window.onclick = () => { // You MUST create the window on the same event // tick/stack as the user-initiated event (eg 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); } 

I browser moderni apriranno la finestra con una pagina vuota (spesso chiamata about:blank ) e, supponendo che l’attività asincrona per ottenere l’URL sia abbastanza veloce, l’UX risultante è per lo più soddisfacente. Se si desidera invece eseguire il rendering di un messaggio di caricamento (o altro) nella finestra mentre l’utente è in attesa, è ansible utilizzare gli URI dei dati .

 window.open('data:text/html,

Loading...<%2Fh1>');

Questo codice mi aiuta Spero che questo aiuti alcune persone

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

L’osservazione che l’evento doveva essere avviato dall’utente mi ha aiutato a capire la prima parte di questo, ma anche dopo che Chrome e Firefox hanno bloccato la nuova finestra. La seconda parte stava aggiungendo target = “_ blank” al link, che è stato menzionato in un commento.

In sintesi: è necessario chiamare window.open da un evento avviato dall’utente, in questo caso facendo clic su un collegamento e tale collegamento deve avere target = “_ blank”.

Nell’esempio seguente il collegamento utilizza 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'); }); 

Prova a utilizzare un elemento di collegamento e fai clic con javascriipt

  

e la sceneggiatura

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

Usalo in questo modo

 //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"; 

questo ha funzionato per me.