2012-07-31 1 views
7

In modernen Browsern verwendet jQuery document.querySelectorAll(), um die Leistung zu verbessern, wenn gültige CSS-Selektoren verwendet werden. Es fällt auf Sizzle zurück, wenn ein Browser den Selektor oder die document.querySelectorAll() Methode nicht unterstützt.Kann ich erzwingen, dass jQuery Sizzle zum Auswerten eines Selektors verwendet, ohne nicht standardmäßige Selektoren zu verwenden?

Allerdings möchte ich immer Sizzle anstelle der nativen Implementierung beim Debuggen eines benutzerdefinierten Selektors verwenden. Nämlich, ich versuche, eine Implementierung von :nth-last-child(), one of the CSS3 selectors that are not supported by jQuery zu kommen. Da dieser Selektor nativ von modernen Browsern unterstützt wird, funktioniert er wie in der verknüpften Frage beschrieben. Es ist genau dieses Verhalten, das das Debuggen meines benutzerdefinierten Selektors behindert, also möchte ich es vermeiden.

Ein billiger Hack, den ich verwenden kann, ist in einem Nicht-Standard-jQuery selector extension fallen, wodurch "Selektor" sozusagen "ungültig". Zum Beispiel, jeder davon aus li:nth-last-child(2) ist visible, kann ich einfach fallen lassen, dass in, drehe diese:

$('li:nth-last-child(2)').css('color', 'red'); 

In diesem:

$('li:nth-last-child(2):visible').css('color', 'red'); 

Dies bewirkt, dass es immer von Sizzle ausgewertet werden. Außer, das erfordert, dass ich eine Annahme meiner Seitenelemente mache, die wahr sein können oder nicht. Und das mag ich wirklich nicht. Ganz zu schweigen davon, dass ich im Allgemeinen nicht standardmäßige Selektoren verwende, es sei denn, dies ist absolut notwendig.

Gibt es eine Möglichkeit die native document.querySelectorAll() Methode in Browsern zu überspringen, die sie unterstützen und jQuery zwingen Sizzle zu verwenden, um einen Selektor anstatt zu bewerten, dass vorzugsweise nicht nicht die Verwendung von Nicht-Standard-Selektoren verwenden? Wahrscheinlich führt dies dazu, dass anstelle von $() eine andere Methode aufgerufen wird, aber es ist viel besser als ein Selector Hack IMO.

+0

Wenn es zum Debuggen ist, könnten Sie versuchen, die Funktion document.querySelectorAll() zu überschreiben oder zu löschen. – jholloman

+0

+1 für den Versuch dies. Genial :) – Spudley

+0

Ich habe es nicht versucht: https://github.com/cowboy/jquery-misc/blob/master/jquery.ba-nth-last-child.js – thirtydot

Antwort

9

könnten Sie legen es einfach null vor jQuery Belastungen, so dass es ihm nicht unterstützt denkt: http://jsbin.com/asipil/2/edit

Kommentar aus:

document.querySelectorAll = null; 
//load jquery, will trigger not supported branch 
//Optionally restore QSA here (save a reference) if needed 

Dies sollte zu this zu false

Demo machen bewerten die null Zeile und wiederholen, und Sie werden sehen, dass es rot wird.

+0

Noch ein Fall von etwas so offensichtlich ist, dass * jemand anders * muss es mir zeigen. Ich kann nicht glauben, dass ich es verpasst habe :) Ich habe vergessen zu erwähnen, dass ich die native Implementierung lieber auch alleine lassen würde, aber wenn es keine andere Lösung gibt, dann wird das wohl reichen. – BoltClock

+0

Funktioniert es? Lassen Browser diese Eigenschaft überschreiben und wenn ja, alle? * bearbeiten: * Scheint zumindest in Chrome zu funktionieren. –

+0

@FelixKling ja, ich habe diesen Trick für einige Randfälle verwendet – Esailija

0

Es scheint, dass jQuery.find standardmäßig auf Sizzle. Dadurch können Sie Ihre Umgebung nicht zerstören, indem Sie eine native Funktion auf null setzen.

https://github.com/jquery/jquery/blob/master/src/sizzle-jquery.js#L3

So sollten Sie in der Lage sein, die folgenden zu tun und es wird immer durch brutzeln gehen.

$.find('li:nth-last-child(2)') 
+0

Wenn der 'document.querySelectorAll' Test zu' true' ausgewertet wird, dann hat 'Sizzle' wurde vor dieser Aufgabe überschrieben. Siehe view-source: http: //code.jquery.com/jquery-1.7.2.js Zeile 5093 – Esailija

+0

Die 'Sizzle'-Methode, auf die in dieser Zeile verwiesen wird, enthält die systemeigenen Aufrufe, bevor sie auf ihre interne Implementierung zurückgreift (I '). Ich vermute, das ist die überschriebene Implementierung, auf die sich @Esailija bezieht. Starten Sie [hier] (https://github.com/jquery/sizzle/blob/master/sizzle.js#L185). Ich habe eine [Geige] (http://jsfiddle.net/BoltClock/mPJge) gemacht und tatsächlich zeigt es ': nth-last-child()' so an, dass es immer noch die native Methode verwendet. – BoltClock

+0

Können Sie darauf hinweisen, wo genau die Unterscheidung gemacht wird? Der einzige Verweis auf "querySelectorAll" ist von 1316 nach unten, und ich sehe nichts, das sagt, dass es 'querySelectorAll' verwenden soll, wenn eine Asserts fehlschlägt. https://github.com/jquery/sizzle/blob/master/sizzle.js#L1316 – travis

3

Da Sie den Code für den Selektor selbst entwickeln, können Sie ihm nicht einfach einen benutzerdefinierten Namen für die Dauer des Entwicklungszyklus geben? Vielleicht geben Sie Ihr eigenes Vendor-Präfix oder etwas? -bolt-nth-last-child()

Auf diese Weise werden Sie wissen, dass der Browser es definitiv nicht unterstützt, so sollte es immer Sizzle verwenden.Wenn Sie mit dem Entwicklungszyklus fertig sind, können Sie das Präfix -bolt- löschen.

Ich weiß, das ist eher eine Umgehung als eine Antwort auf die Frage, aber es scheint wie die einfachste Lösung für mich.

+1

+1 für Kreativität! – BoltClock

Verwandte Themen