189 votes

Événement Cross On Browser Onload et le bouton Précédent

Pour tous les principaux navigateurs (à l'exception d'Internet Explorer), l'événement JavaScript onload ne se déclenche pas lorsque la page est chargée suite à une opération sur le bouton Précédent: il se déclenche uniquement lorsque la page est chargée pour la première fois.

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

119voto

Pumbaa80 Points 27066

Les gars, j'ai trouvé que JQuery n'a qu'un seul effet: la page est rechargée lorsque le dos est enfoncé. Cela n'a rien à voir avec le "prêt".

Comment cela fonctionne? Eh bien, JQuery ajoute un onunload écouteur d'événement.

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

Par défaut, il ne fait rien. Mais de toute façon ce qui semble déclencher une recharge de Safari, Opera et Mozilla, peu importe ce que le gestionnaire d'événement contient.

[modifier(Nickolay): voici pourquoi il fonctionne de cette manière: webkit.org, developer.mozilla.org. Veuillez lire ces articles (ou un résumé dans une autre réponse ci-dessous) et de déterminer si vous avez vraiment besoin de faire cela et de faire votre page de chargement plus lent pour vos utilisateurs.]

Ne peux pas le croire? Essayez ceci:

<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 pouvez comparer à celui-ci sans onunload

<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>

76voto

Nickolay Points 14384

Les navigateurs modernes (Firefox, Safari/Chrome et Opera) prend en charge le spécial "précédent/suivant" cache (je vais l'appeler bfcache, qui est un terme inventé par Mozilla), lorsque l'utilisateur navigue en Arrière. Contrairement à la régulière (HTTP) cache, elle capte l'état complet de la page (y compris l'état de JS, DOM). Cela permet de re-chargement de la page plus rapidement et exactement comme l'utilisateur de gauche.

L' load événement n'est pas censé le feu lorsque la page est chargée de cette bfcache. Par exemple, si vous avez créé votre INTERFACE utilisateur dans la "charge" de gestionnaire, et la "charge" de l'événement est déclenché une fois sur la charge initiale, et la deuxième fois quand la page a été re-chargé de la bfcache, la page serait de dupliquer des éléments de l'INTERFACE.

C'est aussi pourquoi l'ajout de "décharger" le conducteur s'arrête à la page d'être stocké dans le bfcache (rendant plus lent à revenir à l') -- le décharger le gestionnaire peut effectuer des tâches de nettoyage, ce qui pourrait laisser la page en état impraticable.

Pour les pages qui ont besoin de savoir quand ils sont navigué loin/retour, Firefox 1.5+ et la version de Safari avec la correction de bug 28758 soutenir les événements spéciaux appelés "pageshow" et "pagehide".

Références: http://webkit.org/blog/516/webkit-page-cache-ii-the-unload-event/ et https://developer.mozilla.org/En/Using_Firefox_1.5_caching.

31voto

Brian Heese Points 526

J'ai rencontré un problème que mon js n'était pas en cours d'exécution lorsque l'utilisateur a cliqué sur l'arrière ou vers l'avant. J'ai d'abord mis à l'arrêt le navigateur de mise en cache, mais cela ne semble pas te poser problème. Mon javascript a été mis à exécuter après toutes les bibliothèques, etc. où chargés. J'ai vérifier avec le readyStateChange événement.

Après quelques tests, j'ai découvert que la readyState d'un élément dans une page où a été cliqué n'est pas "chargé" mais "complète". L'ajout d' || element.readyState == 'complete' de mon instruction conditionnelle résolu mes problèmes.

Juste pensé que je vous ferais partager mes découvertes, j'espère qu'ils vont aider quelqu'un d'autre.

22voto

Bill Points 1453

OK, voici enfin une solution basée sur ckramer de la solution initiale et palehorse l'exemple qui fonctionne dans tous les navigateurs, y compris l'Opéra. Si vous définissez l'histoire.navigationMode à "compatible" jQuery est prête fonction feu sur le bouton de Retour des opérations à l'Opéra, ainsi que les autres principaux navigateurs.

Cette page a plus d'informations.

Exemple:

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

J'ai testé cela dans Opera 9.5, IE7, FF3 et Safari et ça marche dans tous les d'entre eux.

6voto

thorie Points 106

Je ne pouvais pas obtenir les exemples ci-dessus pour le travail. Je voulais simplement déclencher l'actualisation de certaines modifié div zones en revenant à la page via le bouton retour. L'astuce que j'ai utilisé était de définir un champ caché (appelé "dirty bit") à 1 dès que la div domaines de changé à partir de l'original. Le champ caché conserve sa valeur lorsque je clique sur le dos, de sorte que onload je peux vérifier ce bit. Si c'est réglé, j'ai actualiser la page (ou simplement actualiser les divs). Sur l'origine de la charge, cependant, le bit n'est pas défini, donc je ne perds pas de temps de chargement de 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éclenche correctement à chaque fois que j'ai cliqué sur le bouton de retour.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X