Il ciclo di vita di una pagina HTML ha tre eventi importanti:
-
DOMContentLoaded
: il browser completamente caricato HTML e l’albero DOM è stato creato, ma risorse esterne come immagini<img>
e fogli di stile potrebbero non essere state ancora caricate. -
load
– non viene caricato solo l’HTML, ma anche tutte le risorse esterne: immagini, stili ecc. -
beforeunload/unload
– il l’utente sta lasciando la pagina.
Ogni evento può essere utile:
-
DOMContentLoaded
evento – DOM è pronto , in modo che il gestore possa cercare i nodi DOM, inizializzare l’interfaccia. -
load
evento – le risorse esterne vengono caricate, quindi gli stili vengono applicati, le dimensioni delle immagini sono note ecc. -
beforeunload
evento – l’utente sta uscendo: possiamo controllare se l’utente ha salvato le modifiche e chiedergli se vuole davvero andarsene. - : l’utente ha quasi lasciato, ma possiamo ancora iniziare alcune operazioni, come l’invio di statistiche.
Esploriamo i dettagli di questi eventi.
DOMContentLoaded
L’evento DOMContentLoaded
si verifica sull’oggetto document
.
Noi devi utilizzare addEventListener
per rilevarlo:
Ad esempio:
Nell’esempio il gestore DOMContentLoaded
viene eseguito quando il documento viene caricato, quindi può vedere tutti gli elementi, incluso <img>
di seguito.
Ma non attende il caricamento dell’immagine. Quindi alert
mostra zero dimensioni.
A prima vista, l’evento DOMContentLoaded
è molto semplice. L’albero DOM è pronto: ecco l’evento. Ci sono però alcune peculiarità.
DOMContentLoaded e script
Quando il browser elabora un documento HTML e incontra un tag <script>
, deve essere eseguito prima di continuare a costruire il DOM. Questa è una precauzione, poiché gli script potrebbero voler modificare DOM, e anche document.write
in esso, quindi DOMContentLoaded
deve aspettare.
Quindi DOMContentLoaded si verifica sicuramente dopo tali script:
Nell’esempio sopra, vediamo prima “Libreria caricata …” e poi “DOM pronto!” (tutti gli script vengono eseguiti).
Ci sono due eccezioni a questa regola:
- Script con l’attributo
async
, di cui parleremo più avanti, non bloccareDOMContentLoaded
. - Anche gli script generati dinamicamente con
document.createElement("script")
e poi aggiunti alla pagina web non bloccano questo evento.
DOMContentLoaded e stili
I fogli di stile esterni non influenzano DOM, quindi DOMContentLoaded
non li aspetta.
Ma c’è una trappola. Se abbiamo uno script dopo lo stile, allora quello script deve attendere fino al caricamento del foglio di stile:
La ragione di ciò è che lo script potrebbe voler ottenere le coordinate e altre proprietà degli elementi dipendenti dallo stile, come in l’esempio sopra. Naturalmente, deve attendere il caricamento degli stili.
Poiché DOMContentLoaded
attende gli script, ora attende anche gli stili prima di essi.
Riempimento automatico del browser integrato
I moduli di compilazione automatica di Firefox, Chrome e Opera su DOMContentLoaded
.
Ad esempio, se la pagina ha un form con login e password, e il browser ha ricordato i valori, quindi su DOMContentLoaded
potrebbe provare a riempirli automaticamente (se approvato dall’utente).
Quindi se DOMContentLoaded
viene posticipato da script a caricamento prolungato, quindi attende anche la compilazione automatica. Probabilmente l’hai notato su alcuni siti (se utilizzi la compilazione automatica del browser): i campi di accesso / password non vengono compilati automaticamente immediatamente, ma c’è un ritardo prima del caricamento completo della pagina. Questo è effettivamente il ritardo fino all’evento DOMContentLoaded
.
window.onload
Il load
l’evento sull’oggetto window
si attiva quando viene caricata l’intera pagina, inclusi stili, immagini e altre risorse. Questo evento è disponibile tramite la proprietà onload
.
L’esempio seguente mostra correttamente le dimensioni delle immagini, perché window.onload
attende tutte le immagini:
window.onunload
Quando un visitatore lascia la pagina, l’evento unload
si attiva su window
. Possiamo fare qualcosa che non comporti ritardi, come la chiusura delle finestre popup correlate.
L’eccezione degna di nota è l’invio di analisi.
Diciamo che raccogliamo dati su come è la pagina utilizzato: clic del mouse, scroll, aree della pagina visualizzate e così via.
Naturalmente, unload
si verifica quando l’utente ci lascia e ci piacerebbe salvare i dati sul nostro server.
Invia i dati in background.Il passaggio a un’altra pagina non viene ritardato: il browser lascia la pagina, ma esegue ancora sendBeacon
.
Ecco come usarlo:
- La richiesta viene inviata come POST.
- Possiamo inviare non solo una stringa, ma anche moduli e altri formati, come descritto nel capitolo Fetch, ma di solito è un oggetto stringificato.
- I dati sono limitati da 64 kb.
Quando la richiesta sendBeacon
è terminata, il browser probabilmente ha già lasciato il documento, quindi non c’è modo di ottenere la risposta del server (che di solito è vuota per l’analisi).
C’è anche un flag keepalive
per eseguire tali richieste “after-page-left” nel metodo fetch per richieste di rete generiche. Puoi trovare maggiori informazioni nel capitolo Fetch API.
Se vogliamo annullare la transizione a un’altra pagina, non possiamo farlo qui. Ma possiamo usare un’altra evento – onbeforeunload
.
window.onbeforeunload
Se un visitatore avvia la navigazione aw ay dalla pagina o tenta di chiudere la finestra, il gestore beforeunload
richiede un’ulteriore conferma.
Se cancelliamo l’evento, il browser potrebbe chiedere al visitatore se sono sicuri.
Puoi provarlo eseguendo questo codice e ricaricando la pagina:
Per motivi storici, anche restituire una stringa non vuota conta come annullamento l’evento. Qualche tempo fa i browser lo mostravano come messaggio, ma come dice la specifica moderna, non dovrebbero.
Ecco un esempio:
Il comportamento è stato cambiato , perché alcuni webmaster hanno abusato di questo gestore di eventi mostrando messaggi fuorvianti e fastidiosi. Quindi in questo momento i vecchi browser potrebbero ancora visualizzarlo come un messaggio, ma a parte questo, non c’è modo di personalizzare il messaggio mostrato all’utente.
readyState
Cosa succede se impostiamo il gestore DOMContentLoaded
dopo che il documento è stato caricato?
Naturalmente, non viene mai eseguito.
Ci sono casi in cui non siamo sicuri che il il documento è pronto o no. Vorremmo che la nostra funzione venga eseguita quando il DOM viene caricato, sia ora che in seguito.
La proprietà document.readyState
ci informa sullo stato di caricamento corrente.
Sono disponibili 3 valori possibili:
-
"loading"
– il documento è in caricamento. -
"interactive"
– il documento è stato letto completamente. -
"complete"
– il documento è stato letto completamente e tutte le risorse (come le immagini) sono state caricate troppo.
Quindi possiamo controllare document.readyState
e configurare un gestore o eseguire il codice immediatamente se è pronto.
C’è anche l’evento readystatechange
che si attiva quando lo stato cambia, quindi possiamo stampare tutti questi stati in questo modo:
Il readystatechange
è una meccanica alternativa per tenere traccia dello stato di caricamento del documento, è apparso molto tempo fa. Al giorno d’oggi, è usato raramente.
Vediamo il flusso completo degli eventi per la completezza.
Ecco un documento con <iframe>
, <img>
e gestori che registrano eventi:
L’esempio funzionante è nella sandbox.
L’output tipico:
Il i numeri tra parentesi quadre indicano l’ora approssimativa in cui si verifica. Gli eventi etichettati con la stessa cifra si verificano all’incirca nello stesso momento (± pochi ms).
-
document.readyState
diventainteractive
subito prima diDOMContentLoaded
. Queste due cose in realtà hanno lo stesso significato. -
document.readyState
diventacomplete
quando tutte le risorse (iframe
eimg
) vengono caricati. Qui possiamo vedere che accade più o meno nello stesso periodo diimg.onload
(img
è l’ultima risorsa) ewindow.onload
. Il passaggio allo statocomplete
equivale awindow.onload
. La differenza è chewindow.onload
funziona sempre dopo tutti gli altriload
gestori.
Riepilogo
Eventi di caricamento della pagina:
- L’evento
DOMContentLoaded
si attiva sudocument
quando il DOM è pronto. In questa fase possiamo applicare JavaScript agli elementi.- Script come
<script>https://javascript.info/...</script>
o<script src="https://javascript.info/..."></script>
blocca DOMContentLoaded, il browser attende affinché vengano eseguiti. - Anche le immagini e altre risorse possono continuare a caricarsi.
- Script come
- Il
load
l’evento suwindow
si attiva quando la pagina e tutte le risorse vengono caricate. Lo usiamo raramente, perché di solito non è necessario aspettare così a lungo. - L’evento
beforeunload
suwindow
si attiva quando l’utente desidera lasciare la pagina. Se annulliamo l’evento, il browser chiede se l’utente vuole davvero uscire (ad esempio, abbiamo modifiche non salvate). - L’evento
unload
suwindow
si attiva quando l’utente sta finalmente uscendo, nel gestore possiamo solo fare cose semplici che non comportano ritardi o richieste a un utente. A causa di questa limitazione, viene utilizzato raramente. Possiamo inviare una richiesta di rete connavigator.sendBeacon
. -
document.readyState
è lo stato corrente del documento, le modifiche possono essere monitorato nell’eventoreadystatechange
:-
loading
– il documento è in fase di caricamento. -
interactive
: il documento viene analizzato, avviene più o meno nello stesso momento diDOMContentLoaded
, ma prima. -
complete
: il documento e le risorse vengono caricati, avviene più o meno nello stesso momento diwindow.onload
, ma prima.
-