2012-05-25 9 views
87

Vom jQuery API docs site für ready

alle drei der folgenden Syntaxen sind äquivalent:.

  • $ (document) .ready (Handler)
  • $() bereit (Handler) (dies wird nicht empfohlen)
  • $ (Handler)

Nach Hausaufgaben zu machen - das Lesen und Spielen mit dem source code, habe ich keine Ahnung, warum

$().ready(handler) 

nicht empfohlen. Die erste und dritte Wege, sind genau die gleichen, ruft die dritte Option die Ready-Funktion auf einem Cache gespeicherten jQuery-Objekt mit document:

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

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

Aber die Ready-Funktion hat keine Interaktion mit dem Selektor der ausgewählten Knotenelemente, The ready Quellcode:

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

Wie Sie sehen können, justs den Rückruf an eine interne Warteschlange hinzufügen (readyList) und nicht oder die Elemente im Satz verwenden ändern. Auf diese Weise können Sie die Funktion ready für jedes jQuery-Objekt aufrufen.

Like:

  • regelmäßige Selektor: $('a').ready(handler)DEMO
  • Nonsense Selektor: $('fdhjhjkdafdsjkjriohfjdnfj').ready(handler)DEMO
  • undefiniert Selektor: $().ready(handler)DEMO

Endlich ... zu meiner Frage: Warum $().ready(handler) wird nicht empfohlen?

+0

ich, dass '$ (document) nicht bewusst war. ready (handler) 'könnte short-handed zu' $ (handler) 'sein, das ist ganz nett. Gute Frage. – Richard

+59

@ChaosPandion: Für mich scheint es, als ob er versucht, die Werkzeuge zu verstehen, die er benutzt wie seine Westentasche. Ich würde diese verschwendete Anstrengung nicht wirklich nennen. – Jon

+5

Gute Frage. Wenn jemand interessiert ist, [hier ist ein Leistungsvergleich] (http://jsperf.com/jq-ready-event) ... der (zumindest in Chrome) zeigt, dass die "nicht empfohlene" Version tatsächlich am schnellsten ist. –

Antwort

86

bekam ich eine offizielle Antwort von einem der jQuery-Entwickler:

$().ready(fn) funktioniert nur, weil $() verwendet eine Verknüpfung zu $(document) (jQuery < 1.4)
So $().ready(fn) war ein lesbarer Code.

Aber Leute taten Dinge wie $().mouseover() und alle möglichen anderen Wahnsinn.
und die Leute mussten $([]) tun Objekt eine leere jQuery

So in 1.4 bekommen wir es so $() gibt eine leere jQuery geändert und wir haben nur $().ready(fn) Arbeit, um nicht viel Code zu brechen

$().ready(fn) ist jetzt buchstäblich nur im Kern gepatcht, damit es für den Legacy-Fall richtig funktioniert.

Der beste Platz für die ready Funktion ist $.ready(fn), aber es ist eine wirklich alte Designentscheidung und das ist, was wir jetzt haben.


Ich fragte ihn:

Glauben Sie, dass mehr lesbar $ (fn) als $ ist() bereit (fn).?!

Seine Antwort war:

ich immer tun $ (document) .ready (fn) in tatsächlichen Anwendungen und in der Regel gibt es nur eine doc bereit Block in der Anwendung, um sie wie eine Wartung Sache nicht genau sind.

Ich denke, $ (fn) ziemlich unleserlich ist zu, es ist nur eine Sache, die Sie haben Works wissen ™ ...

+1

Macht Sinn, jQuery ist ziemlich ernsthaft mit Rückwärtskompatibilität – Esailija

+0

@Esailija: Wenn sie so ernst wären, hätten sie nicht das Verhalten von '$()' an erster Stelle * (so albern wie dieses Verhalten gewesen sein könnte) *. Auf der anderen Seite hast du recht. Sie sind nicht immer so geneigt, brechende Änderungen zu machen, wie sich zeigte, als sie versuchten, '.attr()' zu ändern, und machten dann ein paar Tage später einen schnellen Rückfall. Dies hat sie an einige ihrer unglücklichen frühen (und mittleren) Designentscheidungen gebunden. –

+3

@gdoron +1 um es direkt aus dem Maul des Pferdes zu bekommen. –

11

Da die verschiedenen Optionen ziemlich genau dasselbe sind, wie Sie darauf hinweisen, ist es Zeit, den Hut des Bibliotheksautors aufzusetzen und einige Vermutungen anzustellen.

  1. Vielleicht möchten die jQuery Menschen $() für die zukünftige Verwendung haben (zweifelhaft, da $().ready zu arbeiten, selbst dokumentiert ist, wenn nicht zu empfehlen, es würde auch die Semantik von $ verschmutzen, wenn spezieller Gefassten).

  2. Ein viel praktischer Grund: Die zweite Version ist die einzige, die nicht Ende tut bis document Verpackung, so ist es einfacher, zu brechen, wenn Sie den Code beibehalten wird.Beispiel:

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

    Kontrast dies mit

    // BEFORE 
    $().ready(foo); 
    
    // AFTER: breaks 
    $().ready(foo).on("click", "a", function() {}); 
    
  3. Im Zusammenhang mit dem oben: ready ist ein Freak in dem Sinne, dass es (das nur?) Methode, die die gleichen, egal funktionieren wird, was die jQuery Objekt umschließt (auch wenn es nichts umhüllt, wie es hier der Fall ist). Dies ist ein wesentlicher Unterschied zur Semantik anderer jQuery-Methoden. Daher wird zu Recht davon abgeraten.

    Update: Wie Eschlijas Kommentar darauf hinweist, sollte aus technischer Sicht ready wirklich eine statische Methode sein, genau weil es so funktioniert.

Update # 2: an der Quelle Graben, es scheint, dass $() an einem gewissen Punkt in der 1,4 Zweig geändert wurde $([]) übereinstimmen, während in 1.3 es wie $(document) verhielten. Diese Änderung würde die obigen Begründungen verstärken.

+0

Ich habe noch nie einen solchen Code gesehen, das alte Idiom war '$ (document) .ready (function() {// Ihr Code hier});' – Esailija

+0

Ich konnte das zweite Update nicht verstehen, können Sie noch etwas mehr ausführen Bitte? Ich habe nach älteren Versionen gesucht, konnte jedoch keinen Unterschied für dieses Problem mit dem leeren jQuery-Objekt feststellen. – gdoron

+0

@gdoron: Ich meine die Änderung von 'Selektor = Selektor || document' to 'if (! selector) gibt das zurück. – Jon

4

Ich würde sagen, es ist einfach die Tatsache, dass $() gibt ein leer Objekt während $(document) nicht so Ihre ready(), um verschiedene Dinge anwenden; es funktioniert immer noch, aber ich würde sagen, es ist nicht intuitiv.

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

Ja, die gleichen Wahrnehmungen sind in [dieser Antwort] (http://stackoverflow.com/a/2384214/1249581). Die Änderungen erfolgten also in der Version 1.4, die eine neue Rückgaberichtlinie herausgab. – VisioN

+0

Ich habe noch nie jemanden gesehen, der den Dokument-Titel geändert hat, während er einen bereiten Rückruf anbrachte, und ** Sie können es einfach mit Vanille js ohne jQuery machen **. Ich sage nicht, dass es nicht die Antwort sein könnte, aber es ist kein guter Grund. – gdoron

+0

Nun können keine Dokumenteigenschaften oder Methoden über '$()' –

0

Ich denke, das ist wirklich mehr für die Lesbarkeit als alles andere.

Dies ist nicht so ausdruck

$().ready(handler); 

als

$(document).ready(handler) 

Vielleicht versuchen sie irgendeine Form von idiomatischen jQuery zu fördern.

+3

'$ (Dokument) .ready (Handler)' ist besser lesbar als '$ (Handler)', was empfohlen wird ... – gdoron

2

Nur um es ganz offensichtlich, dass es eine Inkonsistenz in den drei ist, und ich hinzugefügt, um die vierte häufig verwendete Form: (function($) {}(jQuery));

Mit dieser Auszeichnung:

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

und diesem Code:

Die angezeigten Ergebnisse des Div aus der letzten Anweisung sind: 0: 9: 9: 9: undefined

SO, nur die Handler und Doc-Versionen sind konsistent mit der jQuery-Konvention der Rückgabe etwas von Nutzen, wie sie den Dokumentenselektor erhalten und mit dem übergebenen Formular müssen Sie etwas zurückgeben (ich würde dies nicht tun würde ich denke, aber setzen es nur um "nach innen" zu zeigen, hat es etwas).

Hier ist eine Geige Version dieses für Neugierige: http://jsfiddle.net/az85G/

+0

I kann nicht sehen, was das Problem damit ist, dass es nichts findet, der Kontext, den Sie für die jQuery gegeben haben, ist 'null' so' .find ('*'). length' return ** 0 **. Findest du etwas Schlechtes mit diesem (offensichtlichen) Verhalten? – gdoron

+0

@gdoron - Ich finde nichts Schlechtes mit diesem Verhalten, ich wollte nur den Unterschied im Vergleich zu zeigen, wenn es einen Selektor hat, der NICHT null ist - beachten Sie, dass dieser leere Selektor wahrscheinlich ist, warum die "schneller" Kommentare sind an anderer Stelle bemerkt, da es ein kleineres zu verarbeitendes Objekt hat, aber in dieser Instanz ein Objekt zurückgibt und nicht "undefiniert". Ich mag die Frage aber wirklich und habe sie aufgepeppt :) –

+0

Der Grund ist, warum es schneller ist, weil der erste "Bruch" Zustand des Ctor ist "wenn (! Selektor) zurückgeben", wenn Sie etwas anderes geben, gibt es 'regex' und andere Dinge gehen weiter ... Danke für freundliche Worte ... Ich denke, ich könnte das jQuery-Team bitten, dies zu beantworten (zur Hölle, es ist nicht meine Bibliothek' :-) '). – gdoron

3

Mehr als wahrscheinlich dies nur eine Dokumentation Bug ist und festgelegt werden soll, ist der einzige Nachteil $().ready(handler) zu verwenden ist es Lesbarkeit ist. Sicher, argumentieren, dass $(handler) genauso unlesbar ist.Ich stimme zu, deshalb verwende ich es nicht.

Sie können auch argumentieren, dass eine Methode schneller ist als eine andere. Wie oft nennen Sie diese Methode jedoch oft hintereinander auf einer einzelnen Seite, um einen Unterschied zu bemerken?

Letztendlich kommt es auf persönliche Vorlieben an. Es gibt keinen Nachteil bei der Verwendung von $().ready(handler) mit Ausnahme des Lesbarkeitsarguments. Ich denke, die Dokumentation ist in diesem Fall nicht führend.

+0

** + 1! ** Sie hatten absolut Recht! Sie werden es lieben, die offizielle jQuery-Antwort zu lesen. Ich habe es als Antwort hinzugefügt. – gdoron

Verwandte Themen