J'utilise jQuery Mobile et j'ai du mal à comprendre les différences entre les événements de page prêts pour les documents classiques et jQuery Mobile.
Quelle est la vraie différence?
Pourquoi devrais-je
<!-- language: lang-js --> $(document).ready() { });
être meilleur que
$(document).on('pageinit') { });
Quel est l'ordre des événements de page, lorsque vous passez d'une page à une autre?
Comment envoyer des données d'une page à une autre et est-il possible d'accéder aux données de la page précédente?
javascript
jquery
html
jquery-mobile
cordova
user2001897
la source
la source
Réponses:
Mise à jour de jQuery Mobile 1.4:
Mon article d'origine était destiné à l'ancienne façon de gérer les pages, essentiellement tout avant jQuery Mobile 1.4. L'ancienne façon de gérer est désormais obsolète et elle restera active jusqu'à (y compris) jQuery Mobile 1.5, vous pouvez donc toujours utiliser tout ce qui est mentionné ci-dessous, au moins jusqu'à l'année prochaine et jQuery Mobile 1.6.
Les anciens événements, dont pageinit n'existent plus, ils sont remplacés par le widget pagecontainer . Pageinit est complètement effacé et vous pouvez utiliser pagecreate à la place, cet événement est resté le même et ne va pas être modifié.
Si vous êtes intéressé par une nouvelle façon de gérer les événements de page, jetez un œil ici , dans tous les autres cas, n'hésitez pas à continuer avec cet article. Vous devriez lire cette réponse même si vous utilisez jQuery Mobile 1.4 +, elle va au-delà des événements de page et vous trouverez probablement beaucoup d'informations utiles.
Contenu plus ancien:
Cet article peut également être trouvé dans le cadre de mon blog ICI .
$(document).on('pageinit')
contre$(document).ready()
La première chose que vous apprenez dans jQuery est d'appeler du code à l'intérieur de la
$(document).ready()
fonction pour que tout s'exécute dès que le DOM est chargé. Cependant, dans jQuery Mobile , Ajax est utilisé pour charger le contenu de chaque page dans le DOM pendant que vous naviguez. À cause de cela, il$(document).ready()
se déclenchera avant le chargement de votre première page et chaque code destiné à la manipulation de la page sera exécuté après un rafraîchissement de la page. Cela peut être un bug très subtil. Sur certains systèmes, il peut sembler que cela fonctionne bien, mais sur d'autres, cela peut provoquer une bizarrerie erratique et difficile à répéter.Syntaxe jQuery classique:
Pour résoudre ce problème (et croyez-moi, c'est un problème), les développeurs de jQuery Mobile ont créé des événements de page. En résumé, les événements de page sont des événements déclenchés dans un point particulier d'exécution de page. L'un de ces événements de page est un événement pageinit et nous pouvons l'utiliser comme ceci:
Nous pouvons aller encore plus loin et utiliser un identifiant de page au lieu du sélecteur de documents. Disons que nous avons une page jQuery Mobile avec un index id :
Pour exécuter du code qui ne sera disponible que pour la page d'index, nous pourrions utiliser cette syntaxe:
L' événement Pageinit sera exécuté à chaque fois que la page est sur le point d'être chargée et affichée pour la première fois. Il ne se déclenchera à nouveau que si la page est actualisée manuellement ou si le chargement de la page Ajax est désactivé. Si vous voulez que le code s'exécute à chaque fois que vous visitez une page, il est préférable d'utiliser l' événement pagebeforeshow .
Voici un exemple de travail: http://jsfiddle.net/Gajotres/Q3Usv/ pour illustrer ce problème.
Encore quelques notes sur cette question. Peu importe si vous utilisez 1 html plusieurs pages ou plusieurs paradigmes de fichiers HTML, il est conseillé de séparer l'ensemble de votre gestion de page JavaScript personnalisée dans un seul fichier JavaScript distinct. Cela permettra d'améliorer votre code, mais vous aurez une bien meilleure vue d'ensemble du code, en particulier lors de la création d'une application jQuery Mobile .
Il y a aussi un autre événement spécial jQuery Mobile et il s'appelle mobileinit . Lorsque jQuery Mobile démarre, il déclenche un événement mobileinit sur l'objet document. Pour remplacer les paramètres par défaut, liez-les à mobileinit . L'un des bons exemples d' utilisation de mobileinit est de désactiver le chargement des pages Ajax ou de modifier le comportement du chargeur Ajax par défaut.
Ordre de transition des événements de page
Tout d'abord, tous les événements peuvent être trouvés ici: http://api.jquerymobile.com/category/events/
Disons que nous avons une page A et une page B, il s'agit d'un ordre de déchargement / chargement:
page B - page de l'événement avant de créer
page B - événement pagecreate
page B - événement pageinit
page A - événement pagebeforehide
page A - pageremove d' événement
page A - événement pagehide
page B - événement pagebeforeshow
page B - événement pageshow
Pour une meilleure compréhension des événements de page, lisez ceci:
pagebeforeload
,pageload
Etpageloadfailed
sont déclenché lorsque une page externe est chargéepagebeforechange
,pagechange
Etpagechangefailed
sont la page des événements de changement. Ces événements sont déclenchés lorsqu'un utilisateur navigue entre les pages des applications.pagebeforeshow
,pagebeforehide
,pageshow
Etpagehide
sont la page des événements de transition. Ces événements sont déclenchés avant, pendant et après une transition et sont nommés.pagebeforecreate
,pagecreate
Etpageinit
sont pour l' initialisation de la page.pageremove
peut être renvoyé puis géré lorsqu'une page est supprimée du DOMExemple de chargement de page jsFiddle: http://jsfiddle.net/Gajotres/QGnft/
Empêcher la transition de page
Si pour une raison quelconque, la transition de page doit être empêchée à certaines conditions, cela peut être fait avec ce code:
Cet exemple fonctionnera dans tous les cas, car il se déclenchera à la mendicité de chaque transition de page et ce qui est le plus important, il empêchera le changement de page avant que la transition de page puisse se produire.
Voici un exemple de travail:
Empêcher la liaison / le déclenchement d'événements multiples
jQuery Mobile
fonctionne d'une manière différente des applications Web classiques. Selon la façon dont vous avez réussi à lier vos événements à chaque fois que vous visitez une page, cela liera les événements à plusieurs reprises. Ce n'est pas une erreur, c'est simplement la façon dontjQuery Mobile
gère ses pages. Par exemple, jetez un œil à cet extrait de code:Exemple d'utilisation de jsFiddle: http://jsfiddle.net/Gajotres/CCfL4/
Chaque fois que vous visiterez la page #index, un événement de clic sera lié au bouton # test-button . Testez-le en passant de la page 1 à la page 2 et inversement plusieurs fois. Il existe plusieurs façons d'éviter ce problème:
Solution 1
La meilleure solution serait d'utiliser
pageinit
pour lier des événements. Si vous jetez un œil à une documentation officielle, vous découvrirez qu'ellepageinit
ne se déclenchera qu'une seule fois, tout comme le document est prêt, il n'y a donc aucun moyen que les événements soient à nouveau liés. C'est la meilleure solution car vous n'avez pas de surcharge de traitement comme lors de la suppression d'événements avec la méthode off.Exemple d'utilisation de jsFiddle: http://jsfiddle.net/Gajotres/AAFH8/
Cette solution de travail est faite sur la base d'un exemple problématique précédent.
Solution 2
Supprimez l'événement avant de le lier:
Exemple d'utilisation de jsFiddle: http://jsfiddle.net/Gajotres/K8YmG/
Solution 3
Utilisez un sélecteur de filtre jQuery, comme ceci:
Étant donné que le filtre d'événements ne fait pas partie du cadre jQuery officiel, il peut être trouvé ici: http://www.codenothing.com/archives/2009/event-filter/
En un mot, si la vitesse est votre principale préoccupation, la solution 2 est bien meilleure que la solution 1.
Solution 4
Un nouveau, probablement le plus simple de tous.
Exemple de travail avec jsFiddle: http://jsfiddle.net/Gajotres/Yerv9/
Tnx au sholsinger pour cette solution: http://sholsinger.com/archive/2011/08/prevent-jquery-live-handlers-from-firing-multiple-times/
pageChange bizarreries d'événement - déclenchement deux fois
Parfois, un événement pagechange peut se déclencher deux fois et n'a rien à voir avec le problème mentionné précédemment.
La raison pour laquelle l'événement pagebeforechange se produit deux fois est due à l'appel récursif dans changePage lorsque toPage n'est pas un objet DOM amélioré jQuery. Cette récursivité est dangereuse, car le développeur est autorisé à modifier le toPage dans l'événement. Si le développeur définit systématiquement à Page une chaîne, dans le gestionnaire d'événements pagebeforechange, qu'il s'agisse ou non d'un objet, une boucle récursive infinie en résultera. L'événement pageload passe la nouvelle page en tant que propriété de page de l'objet de données (cela doit être ajouté à la documentation, il n'est pas répertorié actuellement). L'événement pageload pourrait donc être utilisé pour accéder à la page chargée.
En quelques mots, cela se produit car vous envoyez des paramètres supplémentaires via pageChange.
Exemple:
Pour résoudre ce problème, utilisez n'importe quel événement de page répertorié dans l' ordre de transition des événements de page .
Temps de changement de page
Comme mentionné, lorsque vous passez d'une page jQuery Mobile à une autre, généralement soit en cliquant sur un lien vers une autre page jQuery Mobile qui existe déjà dans le DOM, soit en appelant manuellement $ .mobile.changePage, plusieurs événements et actions ultérieures se produisent. À un niveau élevé, les actions suivantes se produisent:
Il s'agit d'une référence de transition de page moyenne:
Chargement et traitement des pages: 3 ms
Amélioration de la page: 45 ms
Transition: 604 ms
Temps total: 670 ms
* Ces valeurs sont en millisecondes.
Comme vous pouvez le voir, un événement de transition consomme près de 90% du temps d'exécution.
Manipulation des données / paramètres entre les transitions de page
Il est possible d'envoyer un / des paramètre (s) d'une page à une autre pendant la transition de page. Cela peut se faire de plusieurs manières.
Référence: https://stackoverflow.com/a/13932240/1848600
Solution 1:
Vous pouvez transmettre des valeurs avec changePage:
Et lisez-les comme ceci:
Exemple :
index.html
second.html
Solution 2:
Ou vous pouvez créer un objet JavaScript persistant à des fins de stockage. Tant que Ajax est utilisé pour le chargement de la page (et que la page n'est pas rechargée de quelque façon), cet objet restera actif.
Exemple: http://jsfiddle.net/Gajotres/9KKbx/
Solution 3:
Vous pouvez également accéder aux données de la page précédente comme ceci:
L' objet prevPage contient une page précédente complète.
Solution 4:
Comme dernière solution, nous avons une implémentation HTML astucieuse de localStorage. Il ne fonctionne qu'avec les navigateurs HTML5 (y compris les navigateurs Android et iOS) mais toutes les données stockées sont persistantes lors de l'actualisation de la page.
Exemple: http://jsfiddle.net/Gajotres/J9NTr/
Probablement la meilleure solution mais elle échouera dans certaines versions d'iOS 5.X. C'est une erreur bien connue.
Ne pas utiliser
.live()
/.bind()
/.delegate()
J'ai oublié de mentionner (et tnx andleer pour me le rappeler) que l'utilisation on / off pour la liaison / dissociation d'événements, live / die et bind / unbind sont obsolètes.
La méthode .live () de jQuery était considérée comme une aubaine lorsqu'elle a été introduite dans l'API dans la version 1.3. Dans une application jQuery typique, il peut y avoir beaucoup de manipulations DOM et il peut devenir très fastidieux de raccrocher et de décrocher lorsque les éléments vont et viennent. La
.live()
méthode a permis d'accrocher un événement pour la durée de vie de l'application en fonction de son sélecteur. Parfait non? Mal, la.live()
méthode est extrêmement lente. La.live()
méthode accroche en fait ses événements à l'objet document, ce qui signifie que l'événement doit remonter de l'élément qui a généré l'événement jusqu'à ce qu'il atteigne le document. Cela peut prendre énormément de temps.Il est désormais obsolète. Les gens de l'équipe jQuery ne recommandent plus son utilisation et moi non plus. Même s'il peut être fastidieux de connecter et de décrocher des événements, votre code sera beaucoup plus rapide sans la
.live()
méthode qu'avec lui.Au lieu de
.live()
vous devez utiliser.on()
..on()
est environ 2 à 3 fois plus rapide que .live () . Jetez un œil à cette référence de liaison d'événements: http://jsperf.com/jquery-live-vs-delegate-vs-on/34 , tout sera clair à partir de là.Analyse comparative:
Il existe un excellent script conçu pour l' analyse comparative des événements de la page jQuery Mobile . Il peut être trouvé ici: https://github.com/jquery/jquery-mobile/blob/master/tools/page-change-time.js . Mais avant de faire quoi que ce soit avec elle, je vous conseille de supprimer son
alert
système de notification (chaque «page de changement» va vous montrer ces données en arrêtant l'application) et de la changer pour qu'elleconsole.log
fonctionne.Fondamentalement, ce script enregistrera tous vos événements de page et si vous lisez attentivement cet article (descriptions des événements de page), vous saurez combien de temps jQm a consacré aux améliorations de page, aux transitions de page ...
Notes finales
Toujours, et je veux dire toujours lire la documentation officielle de jQuery Mobile . Il vous fournira généralement les informations nécessaires, et contrairement à d'autres documentations, celle-ci est plutôt bonne, avec suffisamment d'explications et d'exemples de code.
Changements:
la source
$().live()
a été déprécié dans jQuery 1.7 et supprimé dans 1.9 donc il devrait vraiment faire partie de toute solution jQuery Mobile. La version de base minimale actuelle pour jQM 1.7.pagecreate
l'événement n'est déclenché qu'une seule fois lors de la création de la page. donc si nous lions des événements de clic à l'intérieur,pagecreate
il ne se déclenchera pas plusieurs fois. Quelque chose que j'ai découvert lors du développement de l'application. Mais nous ne pouvons pas toujours utiliserpagecreate
pour lier des événements, la solution que vous avez donnée est donc la meilleure. +1 donnéCertains d'entre vous pourraient trouver cela utile. Copiez-collez-le sur votre page et vous obtiendrez une séquence dans laquelle les événements sont déclenchés dans la console Chrome ( Ctrl+ Shift+ I).
Vous n'allez pas voir décharger dans la console car elle est déclenchée lorsque la page est en cours de déchargement (lorsque vous vous éloignez de la page). Utilisez-le comme ceci:
Et vous verrez ce que je veux dire.
la source
C'est la bonne façon:
Pour exécuter du code qui ne sera disponible que sur la page d'index, nous pourrions utiliser cette syntaxe:
la source
La différence simple entre un document prêt et un événement de page dans jQuery-mobile est que:
L'événement document ready est utilisé pour toute la page HTML,
Lorsqu'il y a un événement de page, utilisez pour gérer un événement de page particulier:
Vous pouvez également utiliser le document pour gérer l'événement pageinit:
la source
Pendant que vous utilisez .on (), c'est essentiellement une requête en direct que vous utilisez.
D'un autre côté, .ready (comme dans votre cas) est une requête statique. En l'utilisant, vous pouvez mettre à jour dynamiquement les données et ne pas avoir à attendre que la page se charge. Vous pouvez simplement transmettre les valeurs dans votre base de données (si nécessaire) lorsqu'une valeur particulière est entrée.
L'utilisation de requêtes en direct est courante dans les formulaires où nous saisissons des données (compte ou publications ou même commentaires).
la source