2012-03-16 18 views
11

Eventualmente correlato a How to open mailto link in Chrome with Window.open without creating a new tab?mailto link (in chrome) sta attivando window.onbeforeunload - posso impedirlo?

Ciao a tutti. Ho una pagina modulo in cui ho messo una conferma window.onbeforeunload, per impedire alla gente la navigazione via e perdendo i loro cambiamenti per caso:

window.onbeforeunload = function(){ 
    if(changed) 
    return "You have unsaved changes. Do you really want to leave this page without saving?"; 
}; 

dove changed è una variabile ho impostato a true ogni volta che l'utente effettua tutte le modifiche . Va tutto bene. Tuttavia, ho anche aggiunto alcuni link mailto alla pagina, in questo modo:

<a class="button button-alt" href="mailto:[email protected]">Report a problem</a> 

Anche se il mailto non è di uscire dalla pagina (è aprire l'applicazione di posta degli utenti di default), è ancora innescare il evento onbeforeunload, che richiede la casella di conferma, che è fastidioso. Posso aggirarlo impostando target="_blank" sul link, ma poi l'utente rimane in una scheda vuota.

Posso impostare il collegamento mailto per non attivare l'evento onbeforeunload? Ho pensato ad un modo orribilmente hacky di farlo con un'altra variabile javascript temporanea che non conferma la conferma di onbeforeunload, ma sembra piuttosto sporca. Lo farò comunque mentre aspetto una risposta ma qualcuno ha una soluzione migliore?

grazie, max

risposta

9

Immobile fuori della soluzione di epascarello, il seguente codice jQuery dovrebbe fare il trucco:

var ignore_onbeforeunload = false; 
    $('a[href^=mailto]').on('click',function(){ 
     ignore_onbeforeunload = true; 
    }); 

    window.onbeforeunload = function() { 
     if (!ignore_onbeforeunload){ 
      return "Halt! you are not supposed to leave!"; 
     } 
     ignore_onbeforeunload = false; 
    }; 
+0

Questo sembra molto più bello - grazie! –

+0

Davvero? rispondi a un post 3 anni dopo?lol L'unica differenza è l'aggiunta di onclick a un evento non invadente ... lol – epascarello

+0

Si affida a jQuery senza motivo, facendo affidamento sulla variabile globale. La risposta di John Kurlak qui sotto è molto più bella. Usa un iframe nascosto, eliminando totalmente la necessità di JavaScript, per non parlare di jQuery. Può quindi auto-contenere la correzione nel file di modello. – mGuv

4

Aggiungi una bandiera e vedere se è capovolto, impostato il flag sul link click.

var ignore = false 
window.onbeforeunload = function() { 
    if (changed && !ignore) { 
     return "You have unsaved changes. Do you really want to leave this page without saving?"; 
    } else { 
     ignore = false; 
    } 
} 

E il link

<a class="button button-alt" href="mailto:[email protected]" onclick="ignore=true">Report a problem</a> 

Sarebbe meglio aggiungere l'onclick con codice JavaScript.

+0

Grazie, sì è esattamente quello che ho fatto :) Sembra solo un po 'hacky ... –

+0

@MaxWilliams, che dire dei browser che non chiamano 'onbeforeunload' su clic di tale link? Sembra che la chiusura verrà saltata in questo caso. – Qwertiy

1

Un'altra opzione, anche un po 'hacky ma il modo un po' più generico per rendere la beforeunload ignorare certi tipi di collegamenti:

Nel beforeunload, ispezionare il legame che ha causato l'beforeunload, e se non è un http o https link, non infastidire l'utente.

Sfortunatamente non è facile ispezionare il collegamento che ha causato il beforeunload, quindi è qui che diventa un po 'hacky con un gestore onclick e una variabile globale.

var lastClicked = null; 
window.onclick = function(e){ 
    e = e || window.event; 
    lastClicked = e.target 
} 
window.onbeforeunload = function(e){ 
    if (changed && lastClicked && lastClicked.href 
     && lastClicked.href.substring(0,4) == 'http') 
     return "You have unsaved changes"; 
} 

Edit: Quasi dimenticavo, questa risposta viene da qui: https://stackoverflow.com/a/12065766/421243

16

Un davvero semplice correzione di questo è quello di fare qualcosa di simile:

<a href="mailto:[email protected]" target="hidden-iframe">Email me</a> 
<iframe name="hidden-iframe" style="visibility:hidden;position:absolute;"></iframe> 

(E, naturalmente, spostare t ha uno stile al proprio foglio di stile invece di inserirli.)

+0

Sono in ritardo per la festa ma mi sono imbattuto in questo stesso problema. Questa è di gran lunga la soluzione migliore. Gli altri si affidano a un sacco di brutti JavaScript/jQuery. In questo modo puoi auto-contenere la correzione all'interno del template html, usando zero JavaScript. – mGuv

+0

Non funziona su iOS10 –

+0

Questo non funziona su iOS. – khizar

Problemi correlati