Come eseguire uno script all’uscita della pagina

messaggio sull'evento onbeforeunload

Quante volte abbiamo visto questo messaggio mentre cercavamo di uscire da una pagina? Non so voi, ma io molte 🙂

In questo articolo parleremo di come aggiungere e personalizzare questo messaggio, rendendolo il meno intrusivo possibile.

Innanzi tutto, a cosa serve?

A prima vista sembra una cosa inutile utilizzata solamente per recare fastidio (infatti molti spamsite ne fanno uso), per cercare di far eseguire per forza una qualche azione. Ho sempre odiato i siti che ne abusano! Tanto più che te lo propongono in ogni pagina!!!

In realtà questa funzionalità può tornare utile quando abbiamo dei moduli e non vogliamo che i dati immessi dall’utente vadano persi per errore per aver dimenticato di cliccare su un “salva” o chiudendo il browser sbadatamente.

Vediamo quindi come implementare le due diverse situazioni.

Messaggio fastidioso reso il più possibile poco fastidioso 🙂

Vediamo come effettuare un classico messaggio alla chiusura di una pagina. Iniziamo parlando dell’evento incriminato: window.onbeforeunload. Questo evento, come si deduce dal nome, esegue una funzione data nel momento in cui si cerca di lasciare la pagina.

window.onbeforeunload = () => {
    return `Arrivederci e buon viaggio! Torna a trovarci!`;
}

Se inseriamo nel nostro file javascript (oppure tra i tag <script> e </script> le righe qui sopra, all’uscita della pagina verremmo salutati con un bel Ciao! Bello no?

No! Non fatelo assolutamente così! Ve lo proibisco!

Perché? Perché questo ciao ci tormente ogni volta che cerchiamo di uscire dalla pagina! Diventerà un incubo per chiunque!

La cosa migliore da fare è proporlo agli utenti solamente una volta. Questo si può fare con gli storage.

window.onbeforeunload = () => {
    if (!sessionStorage.getItem('messaggioFastidioso')) {
        sessionStorage.setItem('messaggioFastidioso', 1);
        return 'Arrivederci e buon viaggio! Torna a trovarci!';
    }
};

In questo esempio se il cookie messaggioFastidioso non esiste lo creiamo e visualizziamo il messaggio, in caso contrario non facciamo nulla. In pratica il messaggio viene visualizzato solo ogni 24 ore.

Nulla di complicato, vero? Possiamo combinare varie cose fino a ottenere questa simpatica funzioncina di mia invenzione:

//  Mostra un messaggio all'uscita di una pagina

//  @author  Chalda Pnuzig
//  @license https://opensource.org/licenses/gpl-license.php GNU Public License
//  @link    blog.chalda.it
//  @version 1.0.20091217

// Inizializzo il timer
const startTimer = new Date().valueOf();

// Aggiungo una funzione prima che la pagina venga chiusa
window.onbeforeunload = () => {
    // Recupero il tempo trascorso
    const timer = parseInt(new Date().valueOf() - startTimer) / 1000;

    // Controllo di non aver ancora mostrato il messaggio
    const check = sessionStorage.getItem('richiestaCommenti');
    if ((!check || check > startTimer) && (timer > 60)) {
        // Per le prossime 24 ore non mostro più il messaggio
        sessionStorage.setItem('richiestaCommenti', new Date(new Date().setTime(new Date().getTime() + 24 * 3_600_000)));

        // Il messaggio da visualizzare
        return 'Stai leggendo questa pagina da più di un minuto! ' + '\n'
            + 'Probabilmente l\'hai ritenuta interessante!' + '\n'
            + 'Che ne dici di farmelo sapere con un commento?';
    }
}

Come si può capire leggendo i commenti questa funzione mostra il messaggio solamente ogni 24 ore e solamente a chi rimane sulla pagina per più di 60 secondi, in modo da non importunare coloro i quali giungono per sbaglio sul nostro sito (ricordo che il 90% non resta su di una pagina per più di 10 secondi, il restante 10% sono coloro che hanno trovato quello che cercavano 😛 )

Questa funzione è implementata in questo post, quindi, se siete arrivati a leggere fin qui, quando lascerete la pagina vi costringerò a lasciare un messaggio 😀

Controllare se un form è stato compilato ma non spedito

Questa è una cosa tantino più utile 🙂

// Mostra un messaggio se un form è stato compilato ma non spedito

// @author  Chalda Pnuzig
// @license https://opensource.org/licenses/gpl-license.php GNU Public License
// @link    blog.chalda.it
// @version 1.0.20091217

let formModificato = false;

// Cambio lo stato della variabile se si accede ad un elemento del form
document.querySelectorAll('form').forEach(form => {
    form.querySelectorAll('input,select,textarea').forEach(input => {
        input.addEventListener('focus', () => formModificato = true);
    });
    form.addEventListener('submit', () => {
        formModificato = false;
    });
});

window.onbeforeunload = () => {
    if (formModificato) {
        formModificato = false;
        return 'ATTENZIONE!' + '\n' +
            'Non hai ancora salvato quello che stavi facendo!';
    }
}

Mi sembra che anche questo codice non abbia bisogno di molte spiegazioni. In pratica applica una funzione sul focus ad ogni elemento di un form la quale fa cambiare lo stato alla variabile formModificato. Alla chiusura della pagina se tale variabile è true viene visualizzato il messaggio.

Cosa ve ne pare di queste due soluzioni? Vi sembrano utili oppure sono soltanto delle seccature?

Commenti

picchio

grazie a questo post ho imparato molto!

Più di quanto ho imparato ascoltando il prof dell'uni spiegare javascript :D

Grazie ;)

PS: bel blog :)

chalda

Grazie a te per il banner di pollycoke :)

Rafael

Grazie, ottima guida! Ho trovato esattamente quello che cercavo...

chalda

Lieto di esserti stato d'aiuto!

Luca

Ciao, bello questo script... e se volessi all'uscita reindirizzare l'ospite al libro degli ospiti ?? magari con un bottone di conferma ... si può fare ? magari ce l'hai già pronto ? Grazie

chalda

Ciao Luca, basta che prima del return aggiungi

document.location = "http://indirizzo.guestbook.com"
Luca

grazie mille :-) troppo gentile :-) ora provo subito....

Simone

Molto interessante, se la textarea ha un editor come TinyMCE non funziona, come risolvere ?

Simone

chiaramente mi è venuto in mente appena scritto il commento :)

basta aggiungere nella definizione dell'editor

setup : function(ed) {
    ed.onClick.add(function() {
    formModificato=true;
})
Simone

Ho modificato il tuo codice per evitare il messaggio in fase di Submit e gestire anche il tinyMCE

l'ho postato sul mio blog e ti ho linkato ;)

http://symfony-tips.blogspot.com/2010/11/il-form-e-stato-modificato-sei-sicuro.html

Simone

E' esattamente ciò che stavo cercando... Tuttavia lo script non mi funziona :(

Ho provato installando le Jquery con la google api in questo modo:

google.load("jquery", "1.4.2");
google.load("jqueryui", "1.8.1");

e quindi inserendo il codice nella pagina ma non funziona.... qualche idea?

E' proprio ciò che cercavo.... Grazie!

Simone

come non detto...........! funziona!

Le ho provate tutte ma sono stato talmente furbo da non provare a cliccare su una texarea (shame on me...)

Bel post, grazie :)

Matteo

Interessante, ma se qualcuno clicca su una textarea e poi decide di non fare nulla?

chalda

Semplicemente riceve il messaggio e poi fa quello che vuole :-) È solo un avviso, niente di più

vincenzo

scusate e se voglio inserire un messaggio di sconto di un prodotto quando un utente vuole lasciare il mio sito?

e che cliccando su ""annulla"" si viene reindirizzati ad una pagina stabilita per l'offerta?

Chi mi aiuta con il codice?

help me ;-)

Alessio

Ma chi se lo aspettava che ci avresti rigirato il trucco in js?? LOL Vabbè dai, ottimo blog e ottimo script, complimenti. Peccato che tu non abbia moltissime guide, sennò sarebbe molto più facile capire il js :P

alberto

Sono un neofita imbranato ed è quanto dire. Mi sarebbe tanto piaciuto inserire nel mio blog questo script, ma, data la mia ignoranza, non vi sono riuscito nonostante una settimana di tentativi. Potresti, per favore, condurmi per mano nell'inserimento dei vari passaggi e modifiche da effettuare. Te ne sarei molto grato, anche perchè in nessuna altra parte del web ho trovato proprio quello che cercavo (finestra d'uscita solo per chi si èsoffermato sul sito almeno per 60 secondi). Spero nella tua gentilezza e pazineza. Grazie e cordiali saluti. Alberto Serpico

chalda

Ciao Alberto! Il codice devi racchiuderlo nel tag script:

<script type='text/javascript'>
 /* Il codice va qui */
</script>

e posizionarlo possibilmente tra i tag &lt;head&gt; e &lt;/head&gt;. Se avessi problemi mandami un link alla tua pagina così posso controllare dove sbagli ed aiutarti! Ciao!

alberto

Miseria se sei gentile! Inserirò in haed il seguente codice, dopo i vari meta. E' completo?

/**
 * Mostra un messaggio all'uscita di una pagina
 *
 * @author     Chalda Pnuzig
 * @license    http://opensource.org/licenses/gpl-license.php GNU Public License
 * @link       https://blog.chalda.it/
 * @version    1.0.20091217
 *
 */

// Inizializzo il timer
var startTimer = new Date().valueOf();

// Aggiungo una funzione prima che la pagina venga chiusa
window.onbeforeunload = function() {

   // Recupero il tempo trascorso
   var timer = parseInt(new Date().valueOf() - startTimer)/1000;

   // Controllo di non aver ancora mostrato il messaggio
   if ( (document.cookie.indexOf('richiestaCommenti') == -1) &amp;&amp; (timer &gt; 60) ){

      // Per le prossime 24 ore non mostro più il messaggio
      document.cookie = `richiestaCommenti=1; expires=` + new Date(new Date().setTime(new Date().getTime() + 24 * 3600000)).toGMTString();

      // Il messaggio da visualizzare
      return `Stai leggendo questa pagina da più di un minuto!\n`
           + `Probabilmente l'hai ritenuta interessante!\n`
           + `Che ne dici di farmelo sapere con il favore di cliccare sui pulsanti ""mi piace"" di Facebook e di + 1 di Google?`;
   }
}

Ciao Alberto Sito web http://avvocatoserpico.beepworld.it/

alberto

Miseria se sei gentile! Ed allora ne approfitto, riportando il codice che inserirò dopo i meta in di http://avvocatoserpico.beepworld.it/

/**
 *
 * Mostra un messaggio all'uscita di una pagina
 *
 * @author     Giulio ""Chalda"" Bettega
 * @license    http://opensource.org/licenses/gpl-license.php GNU Public License
 * @link       https://blog.chalda.it/?p=145
 * @version    1.0.20091217
 *
 */

// Inizializzo il timer
var startTimer = new Date().valueOf();

// Aggiungo una funzione prima che la pagina venga chiusa
window.onbeforeunload = function() {

   // Recupero il tempo trascorso
   var timer = parseInt(new Date().valueOf() - startTimer)/1000;

   // Controllo di non aver ancora mostrato il messaggio
   if ( (document.cookie.indexOf('richiestaCommenti') == -1) &amp;&amp; (timer &gt; 60) ){

      // Per le prossime 24 ore non mostro più il messaggio
      document.cookie = ""richiestaCommenti=1; expires="" + new Date(new Date().setTime(new Date().getTime() + 24 *

3600000)).toGMTString();

      // Il messaggio da visualizzare
      return `Stai leggendo questa pagina da più di un minuto!\n`
              + `Probabilmente l'hai ritenuta interessante!\n`
              + `Che ne dici di farmelo sapere con il favore di cliccare sui pulsanti ""mi piace"" di Facebook e di + 1 di Google?`;
   }
}

Va bene? Ciao e rigrazie tante. Alberto

chalda

C'è un errore nella funzione che hai postato. In pratica nel testo che hai aggiunto hai inserito un apice singolo, il quale blocca la stringa. Per ovviare al problema devi aggiungere prima il carattere di escape
Sostituisci questa riga:

+ 'Probabilmente l'hai ritenuta interessante!' + '\n'

con questa:

+ 'Probabilmente l\'hai ritenuta interessante!' + '\n'

e tutto dovrebbe andare correttamente. Se dovessi avere altri problemi, in firefox con la scorciatoia CTRL-MAIUSC-J compare la console degli errori che ti può aiutare nell'individuazione dell'errore!

alberto

Da non crederci E' riuscito in questo anche uno come me!!!!!!!!!!!!!!!!!!!!!!!! Grazie, anche perchè vi avevo oramai rinunciato (anche perchè non capivo e tuttora non capisco Query Js Buona domenica. Alberto Serpico

alberto

sono talmente imbranato che, invece, non ci sono riuscito. Amen e grazie lo stesso. Alberto

Anastasia

Ciao! Sono una semplice ""faidate"" e non ci capisco un granchè di html e javascript, anche se mi piace leggere i vostri consigli e provare a metterli in pratica! Il sito che ho ""costruito"" è uno di quelli già pronti, facili per gli imbranati come me! Domanda: - E' possibile inserire un messaggio ( script?) all'uscita dal sito, messaggio fatto, però, da una gif animata che ho trovato sul web e che rappresenta un fiore che scrive ""Arrivederci""? La mia domanda è molto banale e vi ringrazio se solo la prenderete in considerazione!!!! Aspetto con ansia una risposta mooooolto semplice, mi raccomando! Grazie!!!!!!!!

chalda

Ciao Anastasia, Si e no, in quanto il messaggio javascript che appare (la finestrella per intedersi) è obbligatorio per ""fermare"" l'uscita della pagina. È possibile però visualizzare l'immagine prima della finestrella. In questo caso posso darti una mano! :P Ciao

Anastasia

Grazie per la risposta, Chalda, sei molto gentile! Volevo inviarti la gif animata da utilizzare, ma non ci riesco col copia-incolla! Comunque, se tu potessi spiegarmi il procedimento, io ci provo... Non sono sicura del risultato, ma ci provo! :)

bru

Proprio ciò che cercavo, spiegato in modo semplice. grazie

bizio

Grazie per la dritta! L'alert in uscita anche qui è divertente! XD

web designer

Bella come idea, ma a me personalmente da un fastidio boia quando ci sono siti che lo mettono.

Carlo

Su un form moooolto semplice funziona. Ma perchè su una child-page non va?

Elisabetta

Tutto ciò che é sapere é utile, tutto ciò che é scoprire é utile, tutto ciò che é imparare é utile: tutto ciò che voglio (dal web) é sapere, scoprire e imparare.

Grazie a chi insegna senza nulla pretendere.

Marco

Grazie :D

Marco

Ciao! Sapresti dirmi invece come creare una pagina d'uscita? Cioè, l'utente clicca sul link esterno e si apre una pagina d'uscita dove si viene avvisati che si sta abbandonando il sito. Si può fare? Grazie!

demonebianco

Grazie per la spiegazione, ma non ci ho capito molto. Ti chiedo consiglio per una cosa mia personale. Per settare un utente online ho creato una variabile su 'user' dove il campo 'status' è 1 se online e 0 se offline. Se fanno logout allora la variabile cambia in 0 e viene salvata e mi indica che è offline. Se chiude il browser mi frega e rimane online. Allora volevo chiederti, secondo te come posso fare che appena chiudono il browser richiama tacitamente il files logout.php oppure che spunta una finestra di conferma uscita che se la risposta è si, cambia la variabile e chiuse la connessione come fa nel files logout.php? Grazie.

demonebianco

Buonaera, io sto impazzendo in quanto vorrei che all'uscita della pagina si attivano dei comandi siti in redirect logout.php in poche parole, se non si slogano con logut, uscendo dalla pagina di slogano lo stesso, ma come si fa? Ho letto vari forum, ma sono più confuso di prima! In login su database sql si setta una variabile = a 1, quando fa logout si setta e salva a 0. Se esce dalla pagina mi frega, quindi vorrei fare in modo che se esce dalla pagina, lo stesso si attiva il logout, non so se mi sono spiegato bene. Grazie in anticipo

virg

mi ha interessato però per ora non ho risolto, o non ho capito. Io voglio fare una cosa che mi sembra semplice, se l'utente clicca sulla x di chiusura del browser e lo conferma debbo far partire il programma pippo per fare delle operazioni di chiusura. Ciao e grazie per l'attenzione

Mario

Ciao buon giorno, una curiosità. Questa funzione window.onbeforeunload si attiva anche se eseguo il refresh della pagina cliccando il bottone aggiorna del browser, vorrei far in modo che si attivasse soltanto se sto chiudendo il browser e/o dalla scheda.Questo mi serve per una sorta di logout, perché devo aggiornare il campo data_uscita della TBVISITE. Come faccio?Grazie.

vincenzo

sono felice di questa esperienza2

Lascia un commento