2012-04-19 8 views
15

Eventuali duplicati:
window.open(url) different behavior - same code, different timingwindow.open() diverse opere in caso di successo AJAX

Sarà più facile per me spiegare il problema se ho appena vi mostro questo esempio - >http://jsfiddle.net/RU2SM/
Come potete vedere ci sono 2 pulsanti, uno chiamato 'Ajax' e uno chiamato 'Direct' ... Quindi se si fa clic su 'Direct' si apre la finestra (nuova scheda su Chrome) ma se provo a fare window.open() sul gestore di successo AJAX, non funziona stessa strada.
Sono sicuro che il problema è da AJAX ma non ho idea di come risolverlo.
Apprezzerà qualsiasi buona idea. Grazie

+0

possibile duplicazione di [window.open (url) comportamento differente - stesso codice, tempistica diversa) (http://stackoverflow.com/questions/9793774/window-openurl-different-behavior-same-code-different- timing) e [extjs 4.0 comportamento incoerente window.open() quando chiamato all'interno di Ext.Ajax.request()] (http://stackoverflow.com/questions/10049172/extjs-4-0-inconsistent-window-open-behavior -quando-chiamato-dentro-ext-ajax-reques) –

risposta

26

Questo funziona come un fascino:

// Direct window.open() 
$('#btnDirect').on('click',function(){ 
    window.open('http://google.com') 
}) 
var success = false; //NOTE THIS 

// AJAX window.open() 
$('#btnAJAX').on("click", function(){ 
    $.ajax({ 
     url: "/user/login/", 
     context: document.body, 
     async:false, //NOTE THIS 
     success: function(){ //THIS ALSO CHANGED 
     success = true 
     } 
    }); 
    if(success){ //AND THIS CHANGED 
     window.open('http://google.com') 
    } 
}) 

Quello che fa è quando la chiamata Ajax è successo che imposta il successo variabile su true.
L'utilità async:false si assicura che l'istruzione if venga attivata dopo il completamento della chiamata Ajax.
Quindi window.open viene attivato nelle stesse circostanze del collegamento diretto.

+1

Ci sono alcune insidie ​​con richieste non asincrone, non dovresti usarle se possono esserci dei ritardi con la pagina che stai richiedendo. Dalla [documentazione jQuery] (http://api.jquery.com/jQuery.ajax/): "Si noti che le richieste sincrone possono bloccare temporaneamente il browser, disabilitando tutte le azioni mentre la richiesta è attiva." – Gareth

+0

Questo è vero, devi stare attento quando usi questa soluzione, ma è l'unico modo (per quanto ne so) per eseguire entrambe le funzioni nelle stesse circostanze. Perché anche se permetti i pop-up con la versione Ajax crea un pop-up, non apre un'altra scheda come la chiamata diretta Non so esattamente perché c'è una differenza nel comportamento, ma questo sembra fare il trucco –

+0

Grazie, come dici tu "funziona come un fascino ":) Per evitare il blocco prolungato del browser ho aggiunto timeout = 2000 ... – T1000

12

Il problema è che i browser spesso bloccano window.open s a meno che non vengano chiamati in risposta diretta a un'azione dell'utente. Ecco perché il tuo gestore di clic funziona (un clic è un'azione dell'utente) ma il tuo gestore AJAX no.

Una soluzione consiste nell'aprire la finestra durante l'azione di clic iniziale, quindi aggiornare la sua posizione su AJAX riuscito (o chiuderlo di nuovo in caso di errore AJAX).

Altrimenti dovrai consentire all'utente di consentire esplicitamente i popup del tuo dominio nel browser.

+1

Sì, questa è anche la soluzione, ma ho bisogno di aprire una finestra SOLO se ci sono alcune informazioni specifiche nella risposta ... quindi questa non è una buona soluzione per me, ma probabilmente sarà utile per qualcun altro (1+) – T1000

0

come aggiunta vale anche la pena ricordare che l'uso di async: false e quindi chiamare window.open funziona in chrome e firefox ma può causare problemi in safari ... non dà nemmeno informazioni che un popup è stato bloccato

1

modo migliore implementare qualsiasi logica dopo il successo della chiamata ajax, c'è un evento sparato su ogni esecuzione chiamata AJAX cioè $ .ajax.Request.done e $ .ajax.Request.fail. $ .ajax.Request.done (function() {if (successo) {// Implementa logica}});