Existe-t-il un événement de surcharge de navigateur lorsque vous cliquez sur le bouton Retour?

Pour tous les principaux navigateurs (à l'exception d'IE), l' onload JavaScript onload ne déclenche pas lorsque la page se charge à la suite d'une opération de bouton arrière – elle ne se déclenche que lorsque la page est chargée pour la première fois.

Quelqu'un peut-il me signaler un certain code de navigateur croisé (Firefox, Opera, Safari, IE, …) qui résout ce problème? Je suis familier avec l'événement de pageshow de Firefox, mais malheureusement, ni Opera ni Safari ne l'implémentent.

Les gars, j'ai constaté que JQuery n'a qu'un effet: la page est rechargée lorsque vous appuyez sur le bouton Précédent. Cela n'a rien à voir avec " prêt ".

Comment cela marche-t-il? Bien, JQuery ajoute un auditeur d'événements onunload .

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

Par défaut, il ne fait rien. Mais d'une manière ou d'une autre, cela semble déclencher une recharge dans Safari, Opera et Mozilla, quel que soit le contenu du gestionnaire d'événements.

[ Edit (Nickolay) : voici pourquoi il fonctionne de cette façon: webkit.org , developer.mozilla.org . Veuillez lire ces articles (ou mon résumé dans une réponse séparée ci-dessous) et considérez si vous devez vraiment faire cela et rendre votre page plus chargée pour vos utilisateurs.]

Ne peut pas le croire? Essaye ça:

 <body onunload=""><!-- This does the trick --> <script type="text/javascript"> alert('first load / reload'); window.onload = function(){alert('onload')}; </script> <a href="http://stackoverflow.com">click me, then press the back button</a> </body> 

Vous verrez des résultats similaires lors de l'utilisation de JQuery.

Vous voudrez peut-être comparer à celui-ci sans surcharge

 <body><!-- Will not reload on back button --> <script type="text/javascript"> alert('first load / reload'); window.onload = function(){alert('onload')}; </script> <a href="http://stackoverflow.com">click me, then press the back button</a> </body> 

Certains navigateurs modernes (Firefox, Safari et Opera, mais pas Chrome) prennent en charge le cache "back / forward" spécial (je l'appellerai bfcache, qui est un terme inventé par Mozilla), impliqué lorsque l'utilisateur navigue en arrière. Contrairement au cache ordinaire (HTTP), il capture l'état complet de la page (y compris l'état de JS, DOM). Cela lui permet de recharger la page plus rapidement et exactement comme l'a laissé l'utilisateur.

L'événement de load n'est pas censé déclencher lorsque la page est chargée à partir de cette mémoire vive. Par exemple, si vous avez créé votre interface utilisateur dans le gestionnaire de chargement, et que l'événement «chargement» a été déclenché une fois sur la charge initiale, et la deuxième fois que la page a été rechargée à partir du bfcache, la page se terminerait par Éléments d'IU en double.

C'est aussi la raison pour laquelle ajouter le gestionnaire "décharger" arrête la mise en mémoire de la page dans le bfcache (ce qui rend plus lent pour revenir à): le gestionnaire de déchargement pourrait effectuer des tâches de nettoyage, ce qui pourrait laisser la page dans un état inaccessible.

Pour les pages qui doivent savoir quand elles sont déplacées, Firefox 1.5+ et la version de Safari avec correctif pour bug 28758 prennent en charge les événements spéciaux appelés «pageshow» et «pagehide».

Les références:

J'ai rencontré un problème que mes js n'étaient pas en cours d'exécution lorsque l'utilisateur avait cliqué vers l'arrière ou vers l'avant. Je me suis mis d'abord à arrêter le navigateur de la mise en cache, mais cela ne semblait pas être le problème. Mon javascript a été configuré pour s'exécuter après que toutes les bibliothèques, etc. ont été chargées. Je l'ai vérifié avec l'événement readyStateChange.

Après quelques tests, j'ai découvert que l'état prêt d'un élément dans une page où le retour a été cliqué n'est pas «chargé» mais «complet». Ajouter || element.readyState == 'complete' || element.readyState == 'complete' à mon état conditionnel a résolu mes problèmes.

Je pensais simplement partager mes résultats, j'espère qu'ils aideront quelqu'un d'autre.

Modifier pour l'exhaustivité

Mon code était le suivant:

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

Dans l'exemple de code ci-dessus, la variable de script était un élément de script nouvellement créé qui avait été ajouté au DOM.

OK, voici une solution finale basée sur la solution initiale de ckramer et l'exemple de palehorse qui fonctionne dans tous les navigateurs, y compris Opera. Si vous définissez history.navigationMode sur 'compatible', la fonction de jQuery sera activée sur les opérations de Back Button dans Opera ainsi que sur les autres navigateurs majeurs.

Cette page contient plus d'informations .

Exemple:

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

J'ai testé ceci dans Opera 9.5, IE7, FF3 et Safari et ça fonctionne dans tous.

Je ne pouvais pas utiliser les exemples ci-dessus. Je voulais simplement déclencher un rafraîchissement de certaines zones div modifiées en revenant à la page via le bouton arrière. L'astuce que j'ai utilisée était de définir un champ de saisie caché (appelé «bit sale») à 1 dès que les zones div changeaient de l'original. Le champ de saisie caché conserve réellement sa valeur lorsque je clique en arrière, alors je peux vérifier ce bit. Si c'est réglé, je rafraîchis la page (ou je rafraîchis les divs). Sur la charge d'origine, cependant, le bit n'est pas défini, donc je ne perds pas le temps de charger la page deux fois.

 <input type='hidden' id='dirty'> <script> $(document).ready(function() { if ($('#dirty').val()) { // ... reload the page or specific divs only } // when something modifies a div that needs to be refreshed, set dirty=1 $('#dirty').val('1'); }); </script> 

Et il déclencherait correctement chaque fois que j'avais cliqué sur le bouton de retour.

Si je me souviens à juste titre, l'ajout d'un événement de téléchargement () signifie que la page ne peut pas être mise en cache (dans le cache vers l'avant / vers l'arrière) – parce que l'état change / peut changer lorsque l'utilisateur navigue. Donc – il n'est pas sûr de restaurer l'état de la dernière seconde de la page en revenant en naviguant à travers l'objet historique.

Je pensais que ce serait pour "onunload", pas sur le chargement de la page, puisque ne parlons-nous pas d'avoir déclenché un événement en frappant "Back"? $ Document.ready () est destiné aux événements souhaités sur le chargement de la page, peu importe la façon dont vous parvenez à cette page (c.-à-d. La redirection, l'ouverture du navigateur vers l'URL directement, etc.), pas en cliquant sur "Retour", sauf si vous parlez À propos de ce qu'il faut tirer sur la page précédente lorsqu'elle est chargée à nouveau. Et je ne suis pas sûr que la page ne soit pas mise en cache car j'ai constaté que Javascripts sont encore, même si $ document.ready () est inclus dans ceux-ci. Nous avons dû frapper Ctrl + F5 lors de l'édition de nos scripts qui ont cet événement chaque fois que nous les révisons et nous voulons tester les résultats dans nos pages.

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

Est ce que vous voulez pour un événement de surcharge en cas de frappe "Retour" et de déchargement de la page actuelle, et déclenche également quand un utilisateur ferme la fenêtre du navigateur. Cela ressemblait plus à ce qui était souhaité, même si je ne connaissais plus les réponses $ document.ready (). Fondamentalement, la différence est entre un événement tirant sur la page actuelle alors qu'il se ferme ou sur celui qui se charge en cliquant sur "Retour" en cours de chargement. Testé dans l'erreur IE 7, ne peut pas parler pour les autres navigateurs car ils ne sont pas autorisés là où nous sommes. Mais cela pourrait être une autre option.

Je peux confirmer ckramer que l'événement prêt de jQuery fonctionne dans IE et FireFox. Voici un exemple:

 <html> <head> <title>Test Page</title> <script src="http://code.jquery.com/jquery-latest.js" type="text/javascript"></script> <script type="text/javascript"> $(document).ready(function () { var d = new Date(); $('#test').html( "Hi at " + d.toString() ); }); </script> </head> <body> <div id="test"></div> <div> <a href="http://www.google.com">Go!</a> </div> </body> </html> 

Pour les personnes qui ne veulent pas utiliser toute la bibliothèque jquery, j'ai extrait la mise en œuvre dans un code distinct. Il n'y a que 0,4 Ko de gros.

Vous pouvez trouver le code, avec un tutoriel allemand dans ce wiki: http://www.easy-coding.de/wiki/html-ajax-und-co/onload-event-cross-browser-kompatibler-domcontentloaded.html

L' événement prêt de jQuery a été créé pour ce type de problème. Vous voudrez peut-être creuser dans la mise en œuvre pour voir ce qui se passe sous les couvertures.

Bill, j'essaie de répondre à votre question, mais je ne suis pas vraiment sûr de mes suppositions. Je pense que, autrement, les navigateurs IE lors de l'utilisation de l'utilisateur dans une page dans l'histoire, ne chargeront pas seulement la page et ses ressources du cache, mais ils rétabliront également l'état entier de la session DOM (lecture). IE ne fait pas de restauration DOM (ou au bail n'a pas fait) et donc l'événement onload semble nécessaire pour une réinitialisation appropriée de la page.

J'ai essayé la solution de Bill en utilisant $ (document) .ready … mais au début, cela ne fonctionnait pas. J'ai découvert que si le script est placé après la section html, cela ne fonctionnera pas. Si c'est la section principale, elle fonctionnera, mais seulement dans IE. Le script ne fonctionne pas dans Firefox.

OK, j'ai essayé cela et ça marche dans Firefox 3, Safari 3.1.1 et IE7 mais pas dans Opera 9.52.
Si vous utilisez l'exemple ci-dessous (en fonction de l'exemple de palehorse), vous obtenez une fenêtre contextuelle de boîte d'alerte lors de la première chargement de la page. Mais si vous accédez à une autre URL, puis appuyez sur le bouton Précédent pour revenir à cette page, vous ne recevez pas une fenêtre d'alerte dans Opera (mais vous l'utilisez dans les autres navigateurs).

Quoi qu'il en soit, je pense que c'est assez proche pour l'instant. Merci tout le monde!

 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <title>Untitled Document</title> <meta http-equiv="expires" content="0"> <script src="jquery.js" type="text/javascript"></script> <script type="text/javascript"> $(document).ready( function(){ alert('test'); } ); </script> </head> <body> <h1>Test of the page load event and the Back button using jQuery</h1> </body> </html>