Movatterモバイル変換


[0]ホーム

URL:


  1. Web
  2. Les API Web
  3. Manipuler l'historique du navigateur
  4. Utiliser l'API History

Cette page a été traduite à partir de l'anglais par la communauté.Vous pouvez contribuer en rejoignant la communauté francophone sur MDN Web Docs.

View in EnglishAlways switch to English

Utiliser l'API History

L'APIHistory permet à un site web d'interagir avec l'historique de la session du navigateur, c'est-à-dire la liste des pages que la personne a visitées sur une période donnée. Lorsqu'une personne visite de nouvelles pages, par exemple en cliquant sur des liens, ces nouvelles pages sont ajoutées à l'historique de la session. La personne peut alors se déplacer dans cet historique en utilisant les boutons « Précédent » et « Suivant » du navigateur.

L'interface principale de cette API est l'interfaceHistory qui définit deux ensembles de méthodes :

Dans ce guide, nous nous intéresserons surtout au deuxième groupe, dont le comportement peut être plus complexe.

La méthodepushState() permet d'ajouter une nouvelle entrée dans l'historique. La méthodereplaceState() met à jour l'historique de la session pour la page courante. Ces deux méthodes prennent un paramètrestate qui peut contenir n'importe quelobjet sérialisable. Lorsqu'on utilise le navigateur pour accéder à cette entrée d'historique, il déclenchera un évènementpopstate qui contient l'objet d'état associé à cette entrée.

L'objectif principal de cette API est d'assister lesSPA (single-page applications) qui utilisent les API commefetch() pour mettre à jour la page avec du nouveau contenu plutôt que de charger une nouvelle page complète.

SPA et historique de session

Historiquement, les sites web étaient implémentés comme des ensembles de pages. Lorsqu'une personne naviguait vers un autre endroit d'un site en cliquant sur un lien, le navigateur chargeait une nouvelle page à chaque fois.

Si cette approche peut très bien convenir pour de nombreux sites, elle possède quelques inconvénients :

  • Il peut être inefficace de charger toute une page à chaque fois, alors que seule une partie de la page doit être mise à jour.
  • Il est difficile de maintenir l'état de l'application lorsqu'on navigue entre différentes pages.

C'est pour ces raisons que certains sites sont désormais implémentés sous la forme deSPA (single-page applications), où le site est en réalité une seule page, et où lorsqu'une personne clique sur un lien, la page :

  1. Empêche l'action par défaut du navigateur consistant à charger une nouvelle page
  2. Récupère avecfetch() le nouveau contenu à afficher
  3. Met à jour la page avec le nouveau contenu

Par exemple :

js
document.addEventListener("click", async (event) => {  const creature = event.target.getAttribute("data-creature");  if (creature) {    // Empêche le chargement d'une nouvelle page    event.preventDefault();    try {      // Récupère le nouveau contenu      const response = await fetch(`creatures/${creature}.json`);      const json = await response.json();      // Met à jour la page avec le nouveau contenu      displayContent(json);    } catch (err) {      console.error(err);    }  }});

Dans le gestionnaire d'évènement pour le clic, si le lien contient un attribut de données"data-creature", on utilise la valeur de cet attribut pour récupérer un fichier JSON qui contient les nouvelles informations à afficher sur la page.

Le fichier JSON en question pourra ressembler à :

json
{  "description": "Bald eagles are not actually bald.",  "image": {    "src": "images/eagle.jpg",    "alt": "A bald eagle"  },  "name": "Eagle"}

Notre fonctiondisplayContent() met à jour la page avec le contenu du fichier JSON :

js
// Mettre à jour la page avec le nouveau contenufunction displayContent(content) {  document.title = `Creatures: ${content.name}`;  const description = document.querySelector("#description");  description.textContent = content.description;  const photo = document.querySelector("#photo");  photo.setAttribute("src", content.image.src);  photo.setAttribute("alt", content.image.alt);}

Le problème est que cela interfère avec le comportement normal du navigateur pour les boutons « Précédent » et « Suivant ».

Du point de vue de la personne, elle a cliqué et la page a été mise à jour et cela ressemble donc à une nouvelle page. Si la personne clique sur le bouton « Précédent », elle s'attend à revenir à l'état tel qu'il était avant de cliquer sur le lien.

Mais pour le navigateur, le dernier lien n'a pas chargé de nouvelle page (et donc créé de nouvelle entrée dans l'historique), et le bouton « Précédent » ramènera la personne sur la page qui était chargée avant l'ouverture de la SPA.

C'est pour résoudre ce problème que nous avons les méthodespushState(),replaceState(), et l'évènementpopstate. Ils nous permettent de synchroniser les éléments d'historique et d'être notifié·e quand l'entrée courante de l'historique arrive sur une telle page (par exemple, parce que la personne a utilisé les boutons « Précédent » ou « Suivant »).

UtiliserpushState()

On peut ajouter une entrée dans l'historique grâce à notre gestionnaire d'évènement pour le clic :

js
document.addEventListener("click", async (event) => {  const creature = event.target.getAttribute("data-creature");  if (creature) {    event.preventDefault();    try {      const response = await fetch(`creatures/${creature}.json`);      const json = await response.json();      displayContent(json);      // On ajoute une nouvelle entrée à l'historique.      // Cela simule le chargement d'une nouvelle page.      history.pushState(json, "", creature);    } catch (err) {      console.error(err);    }  }});

Dans cet exemple, nous appelonspushState() avec trois arguments :

json

Il s'agit du contenu qui vient d'être récupéré. Il sera stocké avec l'entrée de l'historique et inclus plus tard dans la propriétéstate de l'argument passé au gestionnaire d'évènementspopstate.

""

Cet argument est nécessaire pour la rétrocompatibilité avec les anciens sites et devrait toujours être une chaîne de caractères vide.

creature

Cette valeur sera utilisée comme URL pour l'entrée d'historique. Elle sera affichée dans la barre d'URL du navigateur et utilisée comme valeur pour l'en-têteReferer des requêtes HTTP effectuées par la page. Cette valeur doit avoir lamême origine que la page.

Utiliser l'évènementpopstate

Prenons le scénario suivant :

  1. La personne clique sur un lien dans notre SPA, et nous mettons à jour la page en ajoutant une entrée d'historique A grâce àpushState()
  2. Elle clique ensuite sur un autre lien, et nous mettons à jour la page en ajoutant une entrée d'historique B avecpushState()
  3. Elle clique sur le bouton « Précédent »

L'entrée actuelle est A, et le navigateur déclenche l'évènementpopstate. L'argument passé au gestionnaire d'évènement contient le JSON passépushState() lors de la navigation vers A. Cela signifie que nous pouvons restaurer le contenu correct avec un gestionnaire d'évènement comme celui-ci :

js
// Gestion des boutons précédent/suivantwindow.addEventListener("popstate", (event) => {  // Si un état a été fourni, nous avons une page "simulée"  // et nous mettons à jour la page courante.  if (event.state) {    // On simule le chargement de la page précédente    displayContent(event.state);  }});

UtiliserreplaceState()

Il nous reste une brique à ajouter. Lorsqu'on charge la SPA, le navigateur ajoute une entrée d'historique. Comme il s'agit d'un chargement de page classique, l'entrée dans l'historique ne possède pas d'état associé. Prenons maintenant le scénario suivant :

  1. On charge la SPA : le navigateur ajoute une entrée d'historique
  2. On clique sur un lien dans la SPA : le gestionnaire de clic met à jour la page et rajoute une entrée dans l'historique à l'aide de la méthodepushState()
  3. On clique sur le bouton « Précédent »

Nous voudrions que cela restaure l'état initial de la SPA. Mais comme il s'agit d'une navigation vers le même document, la page n'est pas rechargée, et comme l'entrée d'historique ne possède pas d'état pour la page initiale, nous ne pouvons pas utiliserpopstate pour le restaurer.

La solution consiste à utiliserreplaceState() pour définir l'objet d'état pour la page initiale. Par exemple :

js
// On crée l'état au chargement de la page et on remplace l'entrée courante// de l'historique avec cet étatconst image = document.querySelector("#photo");const initialState = {  description: document.querySelector("#description").textContent,  image: {    src: image.getAttribute("src"),    alt: image.getAttribute("alt"),  },  name: "Home",};history.replaceState(initialState, "", document.location.href);

Au chargement de la page, on collecte tous les endroits de la page qui doivent être restaurés quand on reviendra à l'emplacement initial de la SPA. On utilise ici la même structure que le JSON qui est récupéré lors des autres navigations. Les données sont assemblées dans un objetinitialState qui est passé àreplaceState(), ce qui permet d'associer ces données à l'entrée courante de l'historique.

Désormais, lorsqu'on reviendra au point de départ, l'évènementpopstate contiendra les informations de l'état initial et on pourra utiliser la fonctiondisplayContent() afin de mettre à jour la page.

Un exemple complet

Vous pouvez trouver cet exemple dans son intégralité à l'URLhttps://github.com/mdn/dom-examples/tree/main/history-api, et voir la démo correspondante à l'adressehttps://mdn.github.io/dom-examples/history-api/.

Voir aussi

Help improve MDN

Learn how to contribute

Cette page a été modifiée le par lescontributeurs du MDN.


[8]ページ先頭

©2009-2025 Movatter.jp