Wie erhalte ich das übergeordnete Element der n-ten Ebene eines Elements in jQuery?


150

Wenn ich zum Beispiel das übergeordnete Element der 3. Ebene des Elements erhalten möchte, das ich schreiben muss. $('#element').parent().parent().parent()Gibt es dafür eine optimalere Methode?


2
Ich möchte nur eine Zahl (Stufe) angeben und ein Element abrufen, da mein Element möglicherweise keine Calss-ID oder keinen Namen hat
Artur Keyan

1
Wenn Sie diese Funktionalität wiederverwenden möchten, besteht die optimale Lösung darin, ein jQuery-Plugin zu erstellen.
zzzzBov

3
Siehe jsperf.com/jquery-get-3rd-level-parent für einige Leistungsvergleiche
a'r

1
Ein weiteres gutes Werkzeug ist die Funktion ".closest ()". $ ('li.item'). next ('div') gibt Ihnen den DIV, der der nächste Vorfahr des li.item ist. Gut, wenn Sie nicht wissen, wie viele Ebenen sich das Element befindet, aber den Tagnamen / die Klasse / etwas anderes kennen.
Graham

Antworten:


266

Da parent () die Ahnenelemente zurückgibt, die von den nächstgelegenen zu den äußeren geordnet sind, können Sie sie in eq () verketten :

$('#element').parents().eq(0);  // "Father".
$('#element').parents().eq(2);  // "Great-grandfather".

Kann ich dieses $ ('# Element'). parent () [2] verwenden? oder es muss mit Gleichung (2)
Artur Keyan

1
Dies funktioniert nicht für die Auswahl mehrerer Elemente. Ein sicherer Weg wäre:$('.element').first().parents().eq(num);
zzzzBov

6
@Arthur, using [2]gibt das zugrunde liegende DOM-Element zurück, using eq(2)gibt ein jQuery-Objekt zurück.
Frédéric Hamidi

1
@zzzzBov, sehr wahr, aber im Fall des Fragestellers wird nur ein Element ausgewählt (weil er mit einer ID übereinstimmt).
Frédéric Hamidi

Wenn Sie eine ID "#element" nachschlagen, wird immer nur ein einzelnes Element zurückgegeben, da ID-Lookups so funktionieren. Sie geben das erste Element mit dieser ID im Dom zurück. Wenn Sie andererseits "div # element" oder einen Klassenselektor hätten, hätten Sie Recht.
Henry

29

Abhängig von Ihren Anforderungen können Sie den Selektor .parents () verwenden, wenn Sie wissen, nach welchem ​​Elternteil Sie suchen.

EG: http://jsfiddle.net/HenryGarle/Kyp5g/2/

<div id="One">
    <div id="Two">
        <div id="Three">
            <div id="Four">

            </div>
        </div>
    </div>
</div>


var top = $("#Four").parents("#One");

alert($(top).html());

Beispiel mit Index:

//First parent - 2 levels up from #Four
// I.e Selects div#One
var topTwo = $("#Four").parents().eq(2);

alert($(topTwo ).html());

Ich jetzt so, aber ich möchte Level geben
Artur Keyan

3
Lesen Sie die Antwort weiter unten und alles wird enthüllt! (Ich habe Ihnen Level-Beispiele gegeben)
Henry

Dies funktioniert gut für alle anderen Arten von Selektoren. Wenn Sie beispielsweise die Liste aller Eltern und Eltern von Eltern mit einer bestimmten Klasse anzeigen möchten, werden diese zurückgegeben.
Darksky

8

Sie können dem übergeordneten Ziel eine ID oder Klasse (z. B. myParent) geben, auf die verwiesen wird $('#element').parents(".myParent")


Ich möchte nur eine Zahl angeben und ein Element abrufen, da mein Element möglicherweise keine Calss-ID oder keinen Namen hat
Artur Keyan

6

Ein schnellerer Weg ist die direkte Verwendung von Javascript, z.

var parent = $(innerdiv.get(0).parentNode.parentNode.parentNode);

Dies läuft in meinem Browser erheblich schneller als das Verketten von jQuery- .parent()Aufrufen.

Siehe: http://jsperf.com/jquery-get-3rd-level-parent


Mit "deutlich schneller" sehen wir eine Größenordnung in Bezug auf den Geschwindigkeitsunterschied (mit jQuery 1.10.1 auf Chrome 51). Die Implementierung lohnt sich auf jeden Fall, wenn Sie auf Geschwindigkeit einstellen.
Iain Fraser

5

closest() Ich habe keine Antwort mit gefunden und ich denke, es ist die einfachste Antwort, wenn Sie nicht wissen, wie viele Ebenen das erforderliche Element enthält. Geben
Sie daher eine Antwort: Sie können die closest()Funktion in Kombination mit Selektoren verwenden, um das erste passende Element zu erhalten beim Aufwärtsfahren vom Element nach oben:

('#element').closest('div')    // returns the innermost 'div' in its parents
('#element').closest('.container')    // returns innermost element with 'container' class among parents
('#element').closest('#foo')    // returns the closest parent with id 'foo'

3

Es ist einfach. Benutz einfach

$(selector).parents().eq(0); 

Dabei ist 0 die übergeordnete Ebene (0 ist die übergeordnete Ebene, 1 ist die übergeordnete Ebene der Eltern usw.)


3

Fügen Sie einfach einen :eq()Selektor wie folgt hinzu:

$("#element").parents(":eq(2)")

Sie geben nur den Index an, welcher Elternteil: 0 für den unmittelbaren Elternteil, 1 für den Großelternteil, ...


Dieser Weg ist der schnellste Weg, um Arbeit zu erledigen. Hier ist der Benchmark, um dies zu beweisen: jsperf.com/jquery-get-element-s-nth-parent
Java-Man-Skript

3

Wenn Sie diese Funktionalität wiederverwenden möchten, besteht die optimale Lösung darin, ein jQuery-Plugin zu erstellen:

(function($){
$.fn.nthParent = function(n){
  var $p = $(this);
  while ( n-- >= 0 )
  {
    $p = $p.parent();
  }
  return $p;
};
}(jQuery));

Natürlich können Sie es erweitern, um einen optionalen Selektor und andere solche Dinge zu ermöglichen.

Ein Hinweis: Dies verwendet einen 0basierten Index für Eltern, nthParent(0)ist also dasselbe wie das Aufrufen parent(). Wenn Sie lieber eine 1basierte Indizierung haben möchten, verwenden Sien-- > 0


Ich denke, Sie werden diesen Teil schneller finden: var p = 1 + n; while (p--) { $p = $p.parent(); }und wenn Sie zu 1 wechseln möchten, wobei Javascript "falsey" ist, können Sie Folgendes verwenden: while (n--) { $p = $p.parent();} Speichern eines bedingten Schecks
Mark Schultheiss

@ Mark Schultheiss, es geht nicht nur um Geschwindigkeit, sondern auch um Zuverlässigkeit. Was passiert mit Ihrer Funktion, wenn jemand ignorant anruft nthParent(-2)? Ihr Beispiel ist gebrochen.
zzzzBov

ODER kehren Sie einfach zurück(function($) { $.fn.nthParent = function(n) { return $(this).parents().eq(n); }; }(jQuery));
Mark Schultheiss

@ Mark Schultheiss, wieder Zuverlässigkeit. Meine Funktion gibt den n-tenParent für jedes Element in der Auswahl zurück. Ihre Funktion gibt das n-te Element in der Liste zurück, dessen Liste parentsfür Auswahlen mit mehr als einem Element falsch ist.
zzzzBov

true in Bezug auf -2, und wie in Ihrem Beispiel var p = n >? (1 + n):1; würde die Verwendung von stattdessen in diesem Fall eher das erste übergeordnete Element als "nichts" zurückgeben - oder wo es in meinem Beispiel die Schleife durchbricht. SO sollte es wahrscheinlich sein: (function($) { $.fn.nthParent = function(n) { var $p = $(this); if (!(n > -0)) { return $() }; var p = 1 + n; while (p--) { $p = $p.parent(); } return $p; }; }(jQuery)); wenn Sie nichts zurückgeben möchten.
Mark Schultheiss

3

Wenn Sie ein gemeinsames übergeordnetes Div haben, können Sie den Link parentUntil () verwenden

z.B: $('#element').parentsUntil('.commonClass')

Der Vorteil ist, dass Sie sich nicht daran erinnern müssen, wie viele Generationen zwischen diesem Element und dem gemeinsamen übergeordneten Element (definiert durch commonclass) vorhanden sind.


1

Sie können auch verwenden:

$(this).ancestors().eq(n) 

Beispiel: $(this).ancestors().eq(2)-> der Elternteil des Elternteils von this.


0

Sie könnten so etwas verwenden:

(function($) {
    $.fn.parentNth = function(n) {
        var el = $(this);
        for(var i = 0; i < n; i++)
            el = el.parent();

        return el;
    };
})(jQuery);

alert($("#foo").parentNth(2).attr("id"));

http://jsfiddle.net/Xeon06/AsNUu/


1
Nicht der Downvoter, aber dies ist wahrscheinlich die schlechteste Lösung (dh ineffizient) hier.
Zatatatata

0

Die Verwendung von eq scheint das dynamische DOM zu erfassen, während die Verwendung von .parent (). parent () das ursprünglich geladene DOM zu erfassen scheint (falls dies überhaupt möglich ist).

Ich verwende sie beide für ein Element, auf das Klassen es bei onmouseover angewendet haben. Gleichung zeigt die Klassen, während .parent (). parent () dies nicht tut.


Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.