Window : évènement popstate
Baseline
Widely available
Cette fonctionnalité est bien établie et fonctionne sur de nombreux appareils et versions de navigateurs. Elle est disponible sur tous les navigateurs depuis juillet 2015.
L'évènement popstate de l'interface Window est déclenché lorsque l'entrée d'historique active change pendant que l'utilisateur·ice navigue dans l'historique de session. Cela remplace l'entrée d'historique courante par celle de la dernière page visitée par l'utilisateur·ice ou, si history.pushState() a été utilisé pour ajouter une entrée à la pile d'historique, cette entrée est utilisée à la place.
Syntaxe
Utiliser le nom de l'évènement dans des méthodes comme addEventListener(), ou définir une propriété de gestionnaire d'évènement.
addEventListener("popstate", (event) => { })
onpopstate = (event) => { }
Type d'évènement
Un objet PopStateEvent. Hérite de Event.
Propriétés d'évènement
PopStateEvent.stateLecture seule-
Retourne une copie des informations qui ont été fournies à
pushState()oureplaceState().
Alias du gestionnaire d'évènement
En plus de l'interface Window, la propriété de gestionnaire d'évènement onpopstate est également disponible sur les éléments suivants :
La pile d'historique
Si l'entrée d'historique activée a été créée par un appel à history.pushState() ou a été modifiée par un appel à history.replaceState(), la propriété state de l'évènement popstate contient une copie de l'objet d'état de cette entrée d'historique.
Ces méthodes et leurs évènements associés peuvent être utilisés pour ajouter des données à la pile d'historique, ce qui permet de reconstruire une page générée dynamiquement, ou de modifier l'état du contenu affiché tout en restant sur le même Document.
Notez que le simple fait d'appeler history.pushState() ou history.replaceState() n'exécutera pas l'évènement popstate. L'évènement popstate sera exécuté lors d'une action du navigateur telle qu'un clic sur le bouton de retour ou d'avance (ou un appel à history.back() ou history.forward() en JavaScript).
Les navigateurs ont tendance à gérer l'évènement popstate différemment lors du chargement de la page. Chrome (avant la v34) et Safari émettent toujours un évènement popstate lors du chargement de la page, contrairement à Firefox.
Note :
Lors de l'écriture de fonctions qui traitent l'évènement popstate, il est important de prendre en compte que des propriétés comme window.location reflèteront déjà le changement d'état (si cela a modifié l'URL courante), mais que document pourrait ne pas encore l'être. Si le but est d'intervenir au moment où le nouvel état du document est déjà totalement en place, il convient d'utiliser un appel à la méthode setTimeout() avec un délai nul pour placer effectivement la fonction callback de traitement à la fin de la boucle d'évènements du navigateur : window.onpopstate = () => setTimeout(doSomeThing, 0);
Quand l'évènement popstate est-il envoyé ?
Il est important de comprendre d'abord que — pour lutter contre les fenêtres intempestives — les navigateurs peuvent ne pas déclencher l'évènement popstate tant que la page n'a pas été manipulée par l'utilisateur·ice.
Cette section décrit les étapes suivies par les navigateurs dans les cas où ils peuvent effectivement déclencher l'évènement popstate (c'est-à-dire dans les cas où la page a été manipulée).
Lorsqu'une navigation se produit — soit parce que l'utilisateur·ice active le bouton Retour arrière du navigateur, soit autrement — l'évènement popstate intervient presque à la fin du processus de navigation vers la nouvelle destination. Cela se produit après que la nouvelle destination a été chargée (si besoin), affichée, rendue visible, etc. — après l'envoi de l'évènement pageshow, mais avant la restauration des informations d'état utilisateur persistées et l'envoi de l'évènement hashchange.
Pour mieux comprendre quand l'évènement popstate est déclenché, considérez cette séquence simplifiée d'évènements qui se produit lorsque l'entrée d'historique courante change, soit parce que l'utilisateur·ice navigue sur le site, soit parce que l'historique est parcouru par programmation. Ici, la transition consiste à remplacer l'entrée d'historique courante par une que nous appellerons nouvelle-entrée. L'entrée de la pile d'historique de session de la page courante sera appelée l'entrée-courante.
- Si nouvelle-entrée ne contient pas encore de
Documentexistant, récupérer le contenu et créer sonDocumentavant de continuer. Cela enverra finalement des évènements commeDOMContentLoadedetloadà laWindowcontenant le document, mais les étapes suivantes continueront à s'exécuter entre-temps. - Si le titre de l'entrée-courante n'a pas été défini à l'aide d'une des méthodes de l'API History (
pushState()oureplaceState()), définir le titre de l'entrée sur la chaîne retournée par son attributdocument.title. - Si le navigateur souhaite stocker des informations d'état avec l'entrée-courante avant de la quitter, il le fait à ce moment-là. L'entrée est alors considérée comme ayant un « état utilisateur persistant ». Ces informations que le navigateur peut ajouter à l'entrée de session d'historique peuvent inclure, par exemple, la position de défilement du document, les valeurs des champs de formulaire, et d'autres données similaires.
- Si nouvelle-entrée possède un objet
Documentdifférent de l'entrée-courante, le contexte de navigation est mis à jour de sorte que sa propriétédocumentfasse référence au document de nouvelle-entrée, et le nom du contexte est mis à jour pour correspondre à celui du document désormais courant. - Chaque contrôle de formulaire dans le
Documentde nouvelle-entrée dont l'attributautocompleteest configuré avec le nom de champ de remplissage automatique àoffest réinitialisé. Voir L'attribut HTML de remplissage automatique pour en savoir plus sur les noms de champs de remplissage automatique et leur fonctionnement. - Si le document de nouvelle-entrée est déjà complètement chargé et prêt — c'est-à-dire que son
readyStateest àcomplete— et que le document n'est pas encore visible, il est rendu visible et l'évènementpageshowest déclenché sur le document avec l'attributpersisteddePageTransitionEventdéfinit àtrue. - L'
URLdu document est définie sur celle de nouvelle-entrée. - Si la navigation dans l'historique est effectuée avec le remplacement activé, l'entrée immédiatement précédente à l'entrée de destination (en tenant compte du paramètre
deltades méthodes commego()) est supprimée de la pile d'historique. - Si nouvelle-entrée ne possède pas d'état utilisateur persistant et que le fragment de son URL n'est pas
null, le document est fait défiler jusqu'à ce fragment. - Ensuite, l'entrée-courante est remplacée par nouvelle-entrée. L'entrée de destination est désormais considérée comme courante.
- Si nouvelle-entrée possède des informations d'état sérialisées enregistrées avec elle, ces informations sont désérialisées dans
History.state; sinon,statevautnull. - Si la valeur de
statea changé, l'évènementpopstateest envoyé au document. - Tout état utilisateur persistant est restauré, si le navigateur choisit de le faire.
- Si l'entrée d'origine et la nouvelle entrée partagent le même document, mais ont des fragments différents dans leurs URL, envoyer l'évènement
hashchangeà la fenêtre.
Comme vous pouvez le constater, l'évènement popstate est presque la dernière chose exécutée lors du processus de navigation entre les pages de cette manière.
Exemples
Une page http://exemple.com/exemple.html exécutant le code suivant génèrera un journal comme indiqué :
window.addEventListener("popstate", (event) => {
console.log(
`location: ${document.location}, state: ${JSON.stringify(event.state)}`,
);
});
history.pushState({ page: 1 }, "title 1", "?page=1");
history.pushState({ page: 2 }, "title 2", "?page=2");
history.replaceState({ page: 3 }, "title 3", "?page=3");
history.back(); // Journalise "location: http://exemple.com/exemple.html?page=1, state: {"page":1}"
history.back(); // Journalise "location: http://exemple.com/exemple.html, state: null"
history.go(2); // Journalise "location: http://exemple.com/exemple.html?page=3, state: {"page":3}"
Le même exemple en utilisant la propriété de gestionnaire d'évènement onpopstate :
window.onpopstate = (event) => {
console.log(
`location: ${document.location}, state: ${JSON.stringify(event.state)}`,
);
};
history.pushState({ page: 1 }, "title 1", "?page=1");
history.pushState({ page: 2 }, "title 2", "?page=2");
history.replaceState({ page: 3 }, "title 3", "?page=3");
history.back(); // Journalise "location: http://exemple.com/exemple.html?page=1, state: {"page":1}"
history.back(); // Journalise "location: http://exemple.com/exemple.html, state: null"
history.go(2); // Journalise "location: http://exemple.com/exemple.html?page=3, state: {"page":3}"
Notez que même si l'entrée d'historique originelle (pour http://exemple.com/exemple.html) n'a pas d'objet state associé, un événement popstate est tout de même exécuté lorsque nous activons cette entrée au second appel à history.back().
Spécifications
| Specification |
|---|
| HTML> # event-popstate> |
| HTML> # handler-window-onpopstate> |