88 votes

Pourquoi "$().ready(handler)" n'est-il pas recommandé ?

A partir de la Site de documentation sur l'API jQuery pour ready

Les trois syntaxes suivantes sont équivalentes :

  • $(document).ready(handler)
  • $().ready(handler) (ceci n'est pas recommandé)
  • $(handler)

Après avoir fait ses devoirs - lire et jouer avec le code source Je ne sais pas pourquoi

$().ready(handler) 

n'est pas recommandée. La première et la troisième méthode sont exactement les mêmes, la troisième option appelle la fonction ready sur un objet jQuery mis en cache avec la fonction document :

rootjQuery = jQuery(document);
...
...

// HANDLE: $(function)
// Shortcut for document ready
} else if ( jQuery.isFunction( selector ) ) {
    return rootjQuery.ready( selector );
}

Mais la fonction ready n'a aucune interaction avec le sélecteur des éléments de nœuds sélectionnés. ready code source :

ready: function( fn ) {
    // Attach the listeners
    jQuery.bindReady();
        // Add the callback
    readyList.add( fn );
        return this;
},

Comme vous pouvez le voir, il suffit d'ajouter le rappel à une file d'attente interne( readyList ) et ne modifie ni n'utilise les éléments de l'ensemble. Cela vous permet d'appeler la fonction ready sur chaque objet jQuery.

Comme :

  • régulière sélecteur : $('a').ready(handler) DEMO
  • Absurde sélecteur : $('fdhjhjkdafdsjkjriohfjdnfj').ready(handler) DEMO
  • Non défini sélecteur : $().ready(handler) DEMO

Enfin, j'en viens à ma question : Por qué $().ready(handler) n'est pas recommandé ?

87voto

gdoron Points 61066

J'ai reçu une réponse officielle de l'un des développeurs de jQuery :

$().ready(fn) ne fonctionne que parce que $() était un raccourci vers $(document) (jQuery <1.4)
Donc $().ready(fn) était un code lisible.

Mais les gens avaient l'habitude de faire des choses comme $().mouseover() et toutes sortes d'autres folies.
et les gens ont dû faire $([]) pour obtenir un objet jQuery vide

Dans la version 1.4, nous l'avons donc modifié de la manière suivante $() donne un jQuery vide et nous venons de faire $().ready(fn) de travailler de manière à ne pas casser beaucoup de code

$().ready(fn) est littéralement maintenant juste patché dans le noyau pour qu'il fonctionne correctement dans le cas de l'héritage.

Le meilleur endroit pour le ready est $.ready(fn) Mais il s'agit d'une décision de conception très ancienne et c'est ce que nous avons aujourd'hui.


lui ai-je demandé :

Pensez-vous que $(fn) est plus lisible que $().ready(fn) ? !

Sa réponse a été la suivante :

Je fais toujours $(document).ready(fn) dans les applications actuelles et il n'y a généralement qu'un seul bloc doc ready dans l'application, ce n'est pas vraiment une question de maintenance.

Je pense que $(fn) est assez illisible aussi c'est juste A Thing That You Have To Know Works™ (Une chose qu'il faut savoir fonctionne) ...

11voto

Jon Points 194296

Puisque les différentes options font à peu près la même chose, comme vous le soulignez, il est temps de mettre la casquette d'écrivain de bibliothèque et de faire quelques suppositions.

  1. Peut-être que les adeptes de jQuery aimeraient avoir $() disponibles pour une utilisation future (douteux depuis $().ready est documenté pour fonctionner, même s'il n'est pas recommandé ; il polluerait également la sémantique de $ s'il s'agit d'un cas particulier).

  2. Une raison beaucoup plus pratique : la deuxième version est la seule qui fait no finissent par envelopper document Il est donc plus facile de le casser lors de la maintenance du code. Exemple :

    // BEFORE
    $(document).ready(foo);
    
    // AFTER: works
    $(document).ready(foo).on("click", "a", function() {});

    Contrastant avec

    // BEFORE
    $().ready(foo);
    
    // AFTER: breaks
    $().ready(foo).on("click", "a", function() {});
  3. En rapport avec ce qui précède : ready est un monstre dans le sens où c'est (la seule ?) méthode qui fonctionnera de la même manière quel que soit l'objet jQuery enveloppé (même s'il n'enveloppe rien, comme c'est le cas ici). Il s'agit d'une différence majeure par rapport à la sémantique des autres méthodes jQuery, c'est pourquoi il est à juste titre déconseillé de s'appuyer spécifiquement sur cette méthode.

    Mise à jour : Comme le souligne le commentaire d'Esailija, d'un point de vue technique ready devrait être une méthode statique car elle fonctionne comme suit.

Mise à jour n°2 : En creusant à la source, il semble qu'à un moment donné dans la branche 1.4 $() a été modifié pour correspondre à $([]) alors que dans la version 1.3, il se comportait comme suit $(document) . Cette modification renforcerait les justifications susmentionnées.

4voto

Alex K. Points 67805

Je dirais que c'est simplement le fait que $() renvoie un vide alors que $(document) n'est pas le cas de votre demande ready() à différentes choses ; cela fonctionne toujours, mais je dirais que ce n'est pas intuitif.

$(document).ready(function(){}).prop("title") // the title
$().ready(function(){}).prop("title")  //null - no backing document

3voto

Kevin B Points 57721

Il est plus que probable qu'il s'agisse d'un simple bogue de documentation qui devrait être corrigé. $().ready(handler) est sa lisibilité. Bien sûr, on peut dire que $(handler) est tout aussi illisible. Je suis d'accord, c'est pourquoi je ne l'utilise pas .

Vous pouvez également affirmer qu'une méthode est plus rapide qu'une autre. Cependant, à quelle fréquence appelez-vous cette méthode suffisamment de fois d'affilée sur une même page pour remarquer une différence ?

En fin de compte, il s'agit d'une question de préférence personnelle. Il n'y a pas d'inconvénient à utiliser $().ready(handler) autre que l'argument de la lisibilité. Je pense que la documentation est trompeuse dans ce cas.

2voto

Mark Schultheiss Points 13110

Pour qu'il soit évident qu'il y a une incohérence entre les trois, j'ai ajouté la quatrième forme souvent utilisée : (function($) {}(jQuery));

Avec ce balisage :

<div >one</div>
<div>two</div>
<div id='t'/>

et ce code :

var howmanyEmpty = $().ready().find('*').length;
var howmanyHandler = $(function() {}).find('*').length;
var howmanyDoc = $(document).ready().find('*').length;
var howmanyPassed = (function($) { return $('*').length; }(jQuery));
var howmanyYuck = (function($) {}(jQuery));
var howmanyYuckType = (typeof howmanyYuck);

$(document).ready(function() {
    $('#t').text(howmanyEmpty + ":" + howmanyHandler + ":" 
        + howmanyDoc + ":" + howmanyPassed + ":" + howmanyYuckType);
});

Les résultats affichés du div de la dernière instruction sont les suivants : 0:9:9:9:undefined

Ainsi, seules les versions Handler et Doc sont conformes à la convention jQuery de retourner quelque chose d'utile puisqu'elles obtiennent le sélecteur de document et avec le formulaire Passed vous devez retourner quelque chose (je ne le ferais pas je pense, mais je l'ai mis juste pour montrer "à l'intérieur" qu'il a quelque chose).

Pour les curieux, voici une version pour violon : http://jsfiddle.net/az85G/

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