Esiste un evento onload cross-browser quando si fa clic sul pulsante Indietro?

Per tutti i principali browser (tranne IE), l’evento onload JavaScript non si triggers quando la pagina viene caricata a seguito di un’operazione di pulsante indietro: si triggers solo quando la pagina viene caricata per la prima volta.

Qualcuno può indicarmi qualche esempio di codice cross-browser (Firefox, Opera, Safari, IE, …) che risolve questo problema? Ho familiarità con l’evento pageshow di Firefox, ma sfortunatamente né Opera né Safari lo implementano.

Ragazzi, ho scoperto che JQuery ha un solo effetto: la pagina viene ricaricata quando viene premuto il pulsante Indietro. Questo non ha nulla a che fare con ” pronto “.

Come funziona? Bene, JQuery aggiunge un listener di eventi onunload .

 // http://code.jquery.com/jquery-latest.js jQuery(window).bind("unload", function() { // ... 

Di default, non fa nulla. Ma in qualche modo questo sembra innescare una ricarica in Safari, Opera e Mozilla – indipendentemente dal contenuto del gestore di eventi.

[ modifica (Nickolay) : ecco perché funziona in questo modo: webkit.org , developer.mozilla.org . Si prega di leggere questi articoli (o il mio sumrio in una risposta separata di seguito) e considerare se è davvero necessario farlo e rendere la pagina più lenta per i propri utenti.]

Non ci posso credere? Prova questo:

   click me, then press the back button  

Vedrai risultati simili usando JQuery.

Potresti voler confrontare con questo senza onunload

   click me, then press the back button  

Alcuni browser moderni (Firefox, Safari e Opera, ma non Chrome) supportano la speciale cache “back / forward” (la chiamerò bfcache, che è un termine inventato da Mozilla), coinvolta quando l’utente naviga indietro. A differenza della normale cache (HTTP), cattura lo stato completo della pagina (incluso lo stato di JS, DOM). Ciò gli consente di ricaricare la pagina più rapidamente e esattamente come l’utente lo ha lasciato.

L’evento di load non dovrebbe sparare quando la pagina viene caricata da questo bfcache. Ad esempio, se hai creato l’interfaccia utente nel gestore “load” e l’evento “load” è stato triggersto una volta sul caricamento iniziale, e la seconda volta che la pagina è stata nuovamente caricata dal bfcache, la pagina sarebbe terminata duplicare elementi dell’interfaccia utente.

Questo è anche il motivo per cui l’aggiunta del gestore “unload” impedisce che la pagina venga archiviata nel bfcache (rendendo così più lenta tornare a) – il gestore di scaricamento potrebbe eseguire attività di pulizia, che potrebbero lasciare la pagina in stato non lavorabile.

Per le pagine che hanno bisogno di sapere quando sono in navigazione / ritorno, Firefox 1.5+ e la versione di Safari con la correzione per bug 28758 supportano eventi speciali chiamati “pageshow” e “pagehide”.

Riferimenti:

Mi sono imbattuto in un problema che il mio js non stava eseguendo quando l’utente aveva cliccato avanti o indietro. Per prima cosa ho deciso di interrompere il browser dal caching, ma questo non sembrava essere il problema. Il mio javascript è stato impostato per l’esecuzione dopo che tutte le librerie ecc. Sono state caricate. Li ho controllati con l’evento readyStateChange.

Dopo alcuni test ho scoperto che il readyState di un elemento in una pagina su cui è stato fatto clic sul retro non è “caricato” ma “completo”. Aggiungere || element.readyState == 'complete' || element.readyState == 'complete' alla mia istruzione condizionale ha risolto i miei problemi.

Ho pensato di condividere le mie scoperte, sperando che possano aiutare qualcun altro.

Modifica per completezza

Il mio codice sembrava il seguente:

 script.onreadystatechange(function(){ if(script.readyState == 'loaded' || script.readyState == 'complete') { // call code to execute here. } }); 

Nell’esempio di codice sopra la variabile di script era un elemento di script appena creato che era stato aggiunto al DOM.

OK, ecco una soluzione finale basata sulla soluzione iniziale di ckramer e sull’esempio di Palehorse che funziona in tutti i browser, incluso Opera. Se si imposta history.navigationMode su ‘compatible’, la funzione ready di jQuery attiverà le operazioni del pulsante Indietro in Opera così come negli altri principali browser.

Questa pagina ha più informazioni .

Esempio:

 history.navigationMode = 'compatible'; $(document).ready(function(){ alert('test'); }); 

Ho provato questo in Opera 9.5, IE7, FF3 e Safari e funziona in tutti loro.

Non ho potuto ottenere gli esempi di cui sopra per funzionare. Volevo semplicemente triggersre un aggiornamento di alcune aree div modificate quando si torna alla pagina tramite il pulsante Indietro. Il trucco che ho usato è stato quello di impostare un campo di input nascosto (chiamato “dirty bit”) su 1 non appena le aree div sono cambiate rispetto all’originale. Il campo di input nascosto in realtà mantiene il suo valore quando faccio clic su di esso, quindi onload posso controllare questo bit. Se è impostato, aggiorno la pagina (o aggiorno semplicemente i div). Sul carico originale, tuttavia, il bit non è impostato, quindi non perdo tempo a caricare la pagina due volte.

   

E si innescherebbe correttamente ogni volta che ho fatto clic sul pulsante Indietro.

Se ricordo bene, aggiungere un evento di scaricamento () significa che la pagina non può essere memorizzata nella cache (nella cache in avanti / all’indietro) – perché è cambiamenti di stato / potrebbe cambiare quando l’utente si allontana. Quindi, non è sicuro ripristinare lo stato dell’ultimo secondo della pagina quando si ritorna ad esso navigando attraverso l’object della cronologia.

Ho pensato che sarebbe stato per “onunload”, non per il caricamento della pagina, visto che non stiamo parlando di un evento quando si colpisce “Back”? $ document.ready () è per gli eventi desiderati al caricamento della pagina, indipendentemente da come arrivi a quella pagina (ad es. redirect, aprendo il browser direttamente all’URL, ecc.), non quando fai clic su “Indietro”, a meno che tu non stia parlando su cosa sparare nella pagina precedente quando si carica nuovamente. E non sono sicuro che la pagina non venga memorizzata nella cache poiché ho trovato che i JavaScript sono ancora, anche quando $ document.ready () è incluso in essi. Abbiamo dovuto premere Ctrl + F5 durante la modifica dei nostri script che hanno questo evento ogni volta che li rivediamo e vogliamo testare i risultati nelle nostre pagine.

 $(window).unload(function(){ alert('do unload stuff here'); }); 

è ciò che si vorrebbe per un evento onunload quando si preme “Indietro” e si scarica la pagina corrente e si triggers anche quando un utente chiude la finestra del browser. Sembrava più simile a quello che si desiderava, anche se sono in minoranza con le risposte $ document.ready (). Fondamentalmente la differenza è tra un evento che si triggers sulla pagina corrente mentre sta chiudendo o su quello che viene caricato quando si fa clic su “Indietro” mentre sta caricando. Provato in IE 7 bene, non posso parlare per gli altri browser in quanto non sono ammessi dove siamo. Ma questa potrebbe essere un’altra opzione.

Posso confermare ckramer che l’evento ready di jQuery funziona in IE e FireFox. Ecco un esempio:

   Test Page     
Go!

per le persone che non vogliono utilizzare l’intera libreria jquery ho estratto l’implementazione in un codice separato. È grande solo 0,4 KB.

Puoi trovare il codice, insieme a un tutorial tedesco in questo wiki: http://www.easy-coding.de/wiki/html-ajax-und-co/onload-event-cross-browser-kompatibler-domcontentloaded.html

L’ evento pronto di jQuery è stato creato proprio per questo tipo di problema. Potresti voler scavare nell’implementazione per vedere cosa sta succedendo sotto le coperte.

Bill, oso rispondere alla tua domanda, tuttavia non sono sicuro al 100% con le mie ipotesi. Penso che altri browser di IE quando si porta l’utente a una pagina nella cronologia non solo caricheranno la pagina e le sue risorse dalla cache, ma ripristineranno anche l’intero stato DOM (read session) per esso. IE non esegue il ripristino DOM (o al lease non lo ha fatto) e quindi l’evento onload sembra necessario per la corretta reinizializzazione delle pagine lì.

Ho provato la soluzione di Bill usando $ (document) .ready … ma all’inizio non ha funzionato. Ho scoperto che se lo script viene inserito dopo la sezione html, non funzionerà. Se è la sezione principale, funzionerà, ma solo in IE. Lo script non funziona in Firefox.

OK, ho provato questo e funziona in Firefox 3, Safari 3.1.1 e IE7, ma non in Opera 9.52.
Se si utilizza l’esempio illustrato di seguito (in base all’esempio di Palehorse), viene visualizzata una finestra di avviso quando la pagina viene caricata per la prima volta. Ma se poi vai su un altro URL, e poi premi il pulsante Indietro per tornare a questa pagina, non visualizzi una finestra di avviso in Opera (ma lo fai negli altri browser).

Ad ogni modo, penso che per ora sia abbastanza vicino. Grazie a tutti!

 < !DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">    Untitled Document      

Test of the page load event and the Back button using jQuery

Scarica evento non funziona correttamente su IE 9. L’ho provato con load event (onload ()), funziona perfettamente con IE 9 e FF5 .

Esempio:

 < %@ page language="java" contentType="text/html; charset=ISO-8859-1" pageEncoding="ISO-8859-1"%> < !DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">    Insert title here     

body.jsp

Your Full Name:


Ho usato un modello html. Nel file custom.js di questo modello, c’era una funzione come questa:

  jQuery(document).ready(function($) { $(window).on('load', function() { //... }); }); 

Ma questa funzione non funzionava quando tornavo indietro dopo andare in un’altra pagina.

Quindi, ho provato questo e ha funzionato:

  jQuery(document).ready(function($) { //... }); //Window Load Start window.addEventListener('load', function() { jQuery(document).ready(function($) { //... }); }); 

Ora ho 2 funzioni “ready” ma non danno alcun errore e la pagina funziona molto bene.

Tuttavia, devo dichiarare che ha testato su Windows 10 – Opera v53 e Edge v42 ma nessun altro browser. Tieni presente questo …

Nota: la versione jquery era 3.3.1 e la versione di migrazione era 3.0.0