J'utilise l'API History pour mon application Web et j'ai un problème. Je fais des appels Ajax pour mettre à jour certains résultats sur la page et j'utilise history.pushState () afin de mettre à jour la barre d'emplacement du navigateur sans recharger la page. Ensuite, bien sûr, j'utilise window.popstate afin de restaurer l'état précédent lorsque le bouton retour est cliqué.
Le problème est bien connu - Chrome et Firefox traitent cet événement popstate différemment. Alors que Firefox ne le lance pas lors du premier chargement, Chrome le fait. Je voudrais avoir le style Firefox et ne pas déclencher l'événement en charge car il met simplement à jour les résultats avec exactement les mêmes lors du chargement. Existe-t-il une solution de contournement sauf en utilisant History.js ? La raison pour laquelle je n'ai pas envie de l'utiliser est - il a besoin de beaucoup trop de bibliothèques JS par lui-même et, comme j'ai besoin qu'il soit implémenté dans un CMS avec déjà trop de JS, je voudrais minimiser JS que je mets dedans .
J'aimerais donc savoir s'il existe un moyen de faire en sorte que Chrome ne lance pas 'popstate' lors du chargement ou, peut-être, que quelqu'un a essayé d'utiliser History.js car toutes les bibliothèques se sont rassemblées dans un seul fichier.
la source
Réponses:
Dans Google Chrome dans la version 19, la solution de @spliter a cessé de fonctionner. Comme @johnnymire l'a souligné, history.state dans Chrome 19 existe, mais il est nul.
Ma solution de contournement consiste à ajouter window.history.state! == null pour vérifier si l'état existe dans window.history:
Je l'ai testé dans tous les principaux navigateurs et dans les versions Chrome 19 et 18. Il semble que cela fonctionne.
la source
in
etnull
vérifier avec,!= null
car cela prendra également en chargeundefined
.null
dans voshistory.pushState()
méthodes commehistory.pushState(null,null,'http//example.com/)
. Certes, c'est probablement la plupart des utilisations (c'est ainsi que cela est configuré dans jquery.pjax.js et la plupart des autres démos). Mais si les navigateurs implémententwindow.history.state
(comme FF et Chrome 19+), window.history.state pourrait être non nul lors d'une actualisation ou après un redémarrage du navigateurSi vous ne souhaitez pas prendre de mesures spéciales pour chaque gestionnaire que vous ajoutez à onpopstate, ma solution pourrait vous intéresser. Un gros avantage de cette solution est également que les événements onpopstate peuvent être gérés avant la fin du chargement de la page.
Exécutez simplement ce code une fois avant d'ajouter des gestionnaires onpopstate et tout devrait fonctionner comme prévu (c'est-à-dire comme dans Mozilla ^^) .
Comment ça fonctionne:
Chrome, Safari et probablement d'autres navigateurs Webkit déclenchent l'événement onpopstate lorsque le document a été chargé. Ce n'est pas prévu, donc nous bloquons les événements popstate jusqu'à ce que le premier événement boucle cicle après le chargement du document. Cela est effectué par les appels preventDefault et stopImmediatePropagation (contrairement à stopPropagation, stopImmediatePropagation arrête instantanément tous les appels de gestionnaire d'événements).Cependant, étant donné que le readyState du document est déjà sur «terminé» lorsque Chrome se déclenche par erreur surpopstate, nous autorisons les événements opopstate, qui ont été déclenchés avant la fin du chargement du document, pour autoriser les appels onpopstate avant le chargement du document.
Mise à jour 23/04/2014: Correction d'un bug où les événements popstate étaient bloqués si le script est exécuté après le chargement de la page.
la source
window.history.state
échoue lors du rechargement si un état a été défini. La définition de la variable avant pushState encombre le code. Votre solution est élégante et peut être ajoutée à d'autres scripts, sans impact sur le reste de la base de code. Merci.L'utilisation de setTimeout n'est pas une solution correcte car vous n'avez aucune idée du temps qu'il faudra pour que le contenu soit chargé, il est donc possible que l'événement popstate soit émis après le délai d'expiration.
Voici ma solution: https://gist.github.com/3551566
la source
La solution a été trouvée dans jquery.pjax.js lignes 195-225:
la source
Une solution plus directe que la réimplémentation de pjax est de définir une variable sur pushState et de vérifier la variable sur popState, de sorte que le popState initial ne se déclenche pas de manière incohérente à la charge (pas une solution spécifique à jquery, juste en l'utilisant pour les événements):
la source
window.history.ready
c'est toujours vrai.!window.history.ready && !ev.originalEvent.state
- ces deux choses ne sont jamais définies lorsque j'actualise la page. donc aucun code ne s'exécute.L' événement onpopstate initial de Webkit n'a aucun état attribué, vous pouvez donc l'utiliser pour vérifier le comportement indésirable:
Une solution complète, permettant de revenir à la page d'origine, s'appuierait sur cette idée:
Bien que cela puisse encore se déclencher deux fois (avec une navigation astucieuse), il peut être géré simplement avec une vérification par rapport au href précédent.
la source
window.history.state
est également nulle dans iOS. Il suffit de vérifier si la propriété e.state est nulle.C'est ma solution de contournement.
la source
Voici ma solution:
la source
Le meilleur moyen pour que Chrome ne déclenche pas popstate lors du chargement d'une page est de voter https://code.google.com/p/chromium/issues/detail?id=63040 . Ils savent que Chrome n'est pas conforme aux spécifications HTML5 depuis deux ans maintenant et ne l'ont toujours pas corrigé!
la source
En cas d'utilisation, le
event.state !== null
retour dans l'historique à la première page chargée ne fonctionnera pas dans les navigateurs non mobiles. J'utilise sessionStorage pour marquer quand la navigation ajax démarre vraiment.la source
Les solutions présentées ont un problème lors du rechargement de la page. Ce qui suit semble mieux fonctionner, mais je n'ai testé que Firefox et Chrome. Il utilise la réalité, qu'il semble y avoir une différence entre
e.event.state
etwindow.history.state
.la source
e.event
est undefinedJe sais que vous vous êtes opposé à cela, mais vous devriez vraiment utiliser History.js car il élimine un million d'incompatibilités de navigateur. J'ai suivi la voie de la réparation manuelle pour découvrir plus tard qu'il y avait de plus en plus de problèmes que vous ne découvrirez que plus tard. Ce n'est vraiment pas si difficile de nos jours:
Et lisez l'API sur https://github.com/browserstate/history.js
la source
Cela a résolu le problème pour moi. Tout ce que j'ai fait a été de définir une fonction de délai d'expiration qui retarde l'exécution de la fonction suffisamment longtemps pour manquer l'événement popstate qui est déclenché sur pageload
la source
Vous pouvez créer un événement et le déclencher après votre gestionnaire de chargement.
Notez que ceci est légèrement cassé dans Chrome / Safari, mais j'ai soumis le correctif à WebKit et il devrait être disponible bientôt, mais c'est la manière la plus "correcte".
la source
Cela a fonctionné pour moi dans Firefox et Chrome
la source