Quand exactement le rappel de $ (document) .ready est exécuté?

Supposons que nous .click() un gestionnaire .click() à une balise d'ancrage ( <a> ) dans le rappel de $(document).ready . Ce gestionnaire annule l'action par défaut (suivant le href ) et affiche une alerte.

Ce que j'aimerais savoir, c'est quand exactement le rappel sera exécuté et l'utilisateur peut cliquer sur l'ancre (le document a été affiché dans le navigateur) mais l'événement n'a pas encore été joint.

Voici différentes pages HTML qui contiennent une ancre, mais l'ordre d'inclusion des scripts est différent. Quelle est la différence (le cas échéant) entre eux? Est-ce que différents navigateurs se comportent différemment?

Page 1:

 <html> <head> <title>Test 1</title> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.1/jquery.min.js"></script> <script type="text/javascript"> $(function() { $('a').click(function() { alert('overriding the default action'); return false; }); }); </script> </head> <body> <a href="http://www.google.com">Test</a> </body> </html> 

Page 2:

 <html> <head> <title>Test 1</title> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.1/jquery.min.js"></script> </head> <body> <a href="http://www.google.com">Test</a> <script type="text/javascript"> $(function() { $('a').click(function() { alert('overriding the default action'); return false; }); }); </script> </body> </html> 

Page3:

 <html> <head> <title>Test 1</title> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> </head> <body> <a href="http://www.google.com">Test</a> <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.1/jquery.min.js"></script> <script type="text/javascript"> $(function() { $('a').click(function() { alert('overriding the default action'); return false; }); }); </script> </body> </html> 

Donc, est-il possible qu'un utilisateur soit redirigé vers le href en cliquant sur l'ancre et ne voit jamais l'alerte (ignorant le cas de javascript désactivé bien sûr)? Cela pourrait-il se produire dans l'un des exemples que j'ai fournis?

Tout ce dont j'ai besoin est de s'assurer que le gestionnaire d'événements de click a été attaché à l'ancre avant que l'utilisateur ait la possibilité de cliquer sur cette ancre. Je sais que je peux fournir un href vide, puis l'améliorer progressivement en javascript, mais c'est une question plus générale.

Que se passera-t-il au cas où le HTML serait généré rapidement par le serveur Web, mais la bibliothèque jquery prend du temps pour être extraite d'un serveur éloigné? Est-ce que cela influencera mon scénario? Quel est l'ordre d'inclusion des scripts par rapport au chargement du DOM? Peut-on les faire en parallèle?

L'exemple 3 aura la plus grande chance que l'utilisateur puisse cliquer sur le lien sans que le gestionnaire ne se soit encore associé. Puisque vous chargez la bibliothèque jQuery après le rendu du lien, si les serveurs Google sont un peu lents (ou la recherche DNS prend une seconde), ou l'ordinateur utilisateur est lent à traiter jQuery, le lien n'aura pas son gestionnaire de clics Joint lorsque l'utilisateur essaie de cliquer dessus.

Une autre situation où cela se produit est si vous avez une page de chargement très large ou lente et ce lien est en haut. Ensuite, le DOM peut ne pas être entièrement prêt lorsque des parties sont visibles. Si vous rencontrez un problème comme celui-ci, la chose la plus sûre à faire est:

  1. Chargez jQuery dans la head (exemple 1 ou 2)
  2. Joignez l'événement de clic immédiatement après l'élément <a> , mais pas dans un rappel de DOMReady. De cette façon, il sera appelé immédiatement et n'attendra pas le reste du document.

Une fois qu'un élément est rendu, il peut être saisi du DOM et, par la suite, jQuery peut y accéder:

 <a href="http://www.google.com">Test</a> <script type="text/javascript> // No (document).ready is needed. The element is availible $('a').click(function() { alert('overriding the default action'); return false; }); </script> 

De plus, en s'appuyant sur le commentaire de user384915, si l'action dépend entièrement de JavaScript, ne le rendez pas même dans le cadre du HTML, ajoutez-le après que jQuery est prêt:

 <script type="text/javascript"> jQuery(function($){ $("<a />", { style: "cursor: pointer", click: function() { alert('overriding the default action'); return false; }, text: "Test" }).prependTo("body"); }); </script> 

Vous avez quelques questions différentes ici

Quand exactement le rappel de $ (document) .ready est exécuté?

Il est exécuté dès que le DOM est entièrement chargé. PAS lorsque tout (comme les images) est terminé, le téléchargement comme .load () serait. Il est (en général) avant cela, c'est essentiellement lorsque la page est elle-même construite.

Ce que j'aimerais savoir, c'est quand exactement le rappel sera exécuté

Quand il est cliqué.

Est-il possible pour l'utilisateur de cliquer sur l'ancre (le document a été affiché dans le navigateur), mais l'événement n'a pas encore été joint.

Oui c'est possible. Mais le mettre dans le .ready () vous donne la meilleure chance de ne pas le faire. Il n'y a que 2 façons de le faire pour être «plus sûr» que ce ne sera pas le cas. Ceux-ci utilisent réellement le 'onclick' sur le lien lui-même, et mettent le javascript directement après le lien (et pas dans le .ready ()) afin d'être exécuté immédiatement après la création du lien.

En outre, il n'y a pas de différence entre la façon dont les 2 échantillons de code que vous avez fournis fonctionneront. Cependant, dans le second, vous n'avez pas besoin de mettre le code dans le .ready (), car il existe après le lien, il sera toujours exécuté après la création du lien. Si vous l'avez retiré du .ready (), ce serait la première des deux façons dont j'ai décrit ci-dessus.

De plus, au lieu de mettre «renvoyer faux»; Dans votre rappel, il est préférable d'utiliser .preventDefault () et .stopPropagation () cela vous permettra de spécifier si vous souhaitez empêcher l'action par défaut ou arrêter l'événement de faire de l'eau ou les deux.

Cela dépend de beaucoup de choses. Si vous avez fragmenté l'encodage par exemple, il est possible qu'un utilisateur obtienne un morceau, mais parce que le document n'est pas encore prêt, l'auditeur ne sera pas attaché.

L'événement jQuery ready est l'événement DOMContentLoaded dans les navigateurs compatibles avec W3C (normalisé dans la spécification HTML5), et d'autres alternatives dans d'autres (comme readishtate dans IE).

DOMContentLoaded (MDC)

Découvert à l'objet Document de la page lorsque l'analyse du document est terminée. Au moment où cet événement se déclenche, le DOM de la page est prêt.

Parce que cela se produit avant de le rendre, il serait judicieux de supposer qu'un rappel effectué après cet événement puisse empêcher l'interaction de l'utilisateur sur une page non prête.

Mais comme Peter Michaux l'a souligné dans son article en raison des différences de la façon dont les navigateurs mettent en œuvre cet événement, "une technique robuste pour l'élimination précoce n'est pas possible dans les quatre grands navigateurs".

Je dirais donc que vous ne pouvez pas compter 100% sur l'événement prêt jQuery, mais la plupart du temps, cela fonctionnera très bien.

Dans YUI, il existe les méthodes onContentReady() et onAvailable() . Malheureusement, il n'y a pas d'équivalent dans jQuery. Cependant, il existe un plugin qui a été inspiré par eux:

http://www.thunderguy.com/semicolon/2007/08/14/elementready-jquery-plugin/

Cela devrait vous permettre de lier les événements à l'ancre avant que le DOM soit entièrement chargé.

Votre troisième exemple offre la plus grande chance pour l'utilisateur de cliquer sans que le gestionnaire de remplacement ait été attaché. Le navigateur télécharge généralement et analyse chaque <script> avant de passer à l'étape suivante. Vous effectuez jQuery à partir d'une source externe (Google) – qui, bien que probable, ne soit pas disponible ou lent à charger. Vous avez les deux blocs <script> à la fin de votre document <body> , donc les domaines précédents de la page seront probablement déjà téléchargés et rendus à l'écran pendant que ces deux derniers scripts sont gérés. Bien que cette approche soit préconisée pour présenter une expérience de charge de page réactive à l'utilisateur, ils pourraient cliquer pendant cette période incertaine, et bien sûr, le gestionnaire de remplacement n'a pas encore été attaché.

Il y a un article YUIblog intéressant sur les scripts et l'ordre de chargement ici .

Bien sûr, il est possible de «tricher» l'avertissement d'alerte (même si le Javascript est activé). Essayez de faire glisser le lien dans le champ url et vous verrez qu'il sera exécuté sans cet avertissement. Ceci est particulièrement problématique si le lien déclenche l'action de suppression.

A propos du rappel de document. Je pose aussi un tel problème. Laisse-moi expliquer. Nous faisons un projet où tous les formulaires s'affichent dans les fenêtres contextuelles (fenêtre jQuery). Donc, lorsque le popup est fermé (pour l'instant), la page est rechargée, et j'ai eu des cas où je suis redirigé vers un autre écran au lieu d'ouvrir un nouveau menu contextuel.

Je suis entièrement d'accord avec user384915 pour mettre javascript directement sur l'événement onClick ou encore mieux pour href tag.