2010-02-15 10 views
29

Ich habe ein A-Tag, das die Animation von auslöst es ist Ur-Ur-Urgroßvater. Alles Folgende wird funktionieren, aber welches ist am effizientesten und warum?Welches ist effizienter: .parent(). Parent(). Parent() ~ oder ~ eltern (". Foo") ~ oder ~ am nächsten (". Foo")

$(this).parent().parent().parent().parent().parent().animate(...); 

$(this).parents(".foo").animate(...); 

$(this).closest(".foo").animate(...); 

Ich vermute, dass der erste sein könnte, da es die deutlichste ist, aber aus Wartungsgründen (die Verschachtelung ändern kann) ich die zweite bevorzugen. Sie alle erscheinen, um in der Praxis reibungslos zu laufen.

+1

Ich glaube, Sie Ihre eigene Frage dort beantwortet. Wenn es glatt genug ist, sollte es nicht mikrooptimiert werden, wenn die Wartbarkeit so stark leiden würde. :) – deceze

Antwort

8

Nun am nächsten ist nur nützlich, wenn Sie auf dem 'angeklickt' Element auf oder auf der gleichen Ebene gehen.

Wenn Sie zum Beispiel auf Folowing Szenario haben:

<div class="controls radio-other"> 
    <label class="radio"><input type="radio" name="item">Option one</label> 
    <label class="radio"><input type="radio" name="item">Option two</label> 
    <label class="radio"><input type="radio" name="item" class="other-option" data-othertarget="#otherone"> Other... </label> 
    <input type="text" placeholder="Alternative answer" id="otherone" class="hidden"> 
</div> 

Dann closest('#otherone') nicht die versteckten Textfeld finden auf $('.other-option').click() Die bessere Lösung ist in diesem Szenario $(this).parentsUntil('.radio-other').find('#otherone')

Ein Blick auf meine zu verwenden ist Antwort Ich habe hier eine jsperf gemacht, die obige Szenario mit verschiedenen Lösungen widerspiegelt. Verwenden Sie einfach das, was für Ihr HTML-Szenario am nützlichsten ist. das Ergebnis ist, dass parent().parent() ist die schnellste Methode, aber das ist nicht immer eine gute Option, wenn Ihr HTML flexibler im Einsatz ist. Fügen Sie ein Div Elternteil und die parent().parent() bricht.

+0

Ausgezeichnete Analyse, danke . – graphicdivine

6

Es ist eine sehr gute Sache, dass Sie Leistungsmessungen durchgeführt haben. Genau das sollte in solchen Szenarien getan werden. Wenn in der Praxis alles glatt läuft und Sie mit der Leistung zufrieden sind, wählen Sie die am besten lesbare aus (die zweite und dritte sehen gut aus).

3

Ich denke, ich sah eine Präsentation von John Resig sagen, dass am nächsten() ist optimiert, und es macht Sinn. Closest() ist eine neuere Ergänzung von jQuery und löst genau diese hässliche parent(). Parent() Kette. Auf der anderen Seite gibt parents() ein Array von Eltern zurück, die zu Ihrer foo-Klasse passen und ist gieriger in Bezug auf die Suche im Vergleich zu engsten(), die das erste Element findet und die Suche stoppt.

Ich würde wetten, dass am nächsten() am effizientesten ist, wenn Sie nach dem nächsten Spiel suchen.

2

Ich kann die reale Geschwindigkeit nicht kommentieren, aber die erste verbindet dich mit einer spezifischen Hierarchie von Elementen, vor der ich zurückschrecken würde.

Persönlich versuche ich Klassenselektoren ohnehin sparsam zu verwenden. Mir ist klar, dass es oft keinen anderen Weg gibt, aber wenn ich einen ID-Selektor berücksichtigen kann, dann weiß ich, dass sich die Performance sowieso verbessern wird.

50

Hier ist ein analyzation:

  • parent() geht nur eine Ebene in dem DOM-Baum.
  • parents(".foo") geht bis zur Wurzel und wählt nur die Elemente aus, die dem angegebenen Selektor .foo entsprechen.
  • closest(".foo") läuft bis zur Wurzel, stoppt aber, sobald ein Element mit dem Selektor .foo übereinstimmt.

So würde ich die letzte, closest(".foo") wählen. Der Grund:

  • Es ist besser als parent Chaining, denn wenn Ihr Dokument ändert sich, weil Sie eine Hierarchie entfernt oder hinzugefügt, die Sie nicht die jQuery-Code ändern müssen.
  • Es ist besser als parents(".foo"), weil es stoppt, sobald ein Spiel gefunden wurde.
+6

Was ist der Grund für die Down-Abstimmung? Gibt es Einwände gegen meine Antwort? – Gumbo

+0

Upvoted-Kommentar, um gezielt nach einem Grund zu fragen (wie SO selbst). Deshalb bist du ein Mod, ich spreche. –

+1

@Josh Smith: Ich bin immer darauf aus, meine Antwort zu verbessern, wenn sie falsch ist oder einen wichtigen Aspekt verpasst. – Gumbo

2

Sie können auch parents('.foo:first') verwenden. Ich denke, ist ungefähr das gleiche wie closest().

2

Ein kurzer Test in Firefox 3.6.3 zeigt, dass parents('.foo').eq(0) tatsächlich deutlich schneller ist als closest('.foo'). Es ist strittig, ob es so wartbar ist, aber es könnte sich in bestimmten Szenarien als "effizienter" erweisen.

+6

Wenn Sie nur auf Geschwindigkeit zielen, sollten Sie die jQuery-Fassade überhaupt nicht verwenden, sondern nur einfaches DOM-Traversing: '$ (this.parentNode.parentNode.parentNode.parentNode.parentNode) .animate (...)' – Gumbo