Jak uzyskać element nadrzędny n-tego poziomu elementu w jQuery?


151

Kiedy chcę na przykład uzyskać rodzica trzeciego poziomu elementu, który muszę napisać $('#element').parent().parent().parent()Czy jest na to bardziej optymalna metoda?


2
Chcę dać tylko numer (level) i uzyskać elementu, ponieważ mój element może nie mieć żadnego identyfikatora calss lub nazwę
Artur Keyan

1
Jeśli planujesz ponownie wykorzystać tę funkcjonalność, optymalnym rozwiązaniem jest stworzenie wtyczki jQuery.
zzzzBov

3
Zobacz jsperf.com/jquery-get-3rd-level-parent, aby zapoznać się z niektórymi porównaniami wydajności
a'r

1
Kolejnym dobrym narzędziem jest funkcja „.closest ()”. $ ('li.item'). najbliższe ('div') da ci DIV, który jest najbliższym przodkiem li.item. Dobre w przypadku, gdy nie wiesz, o ile poziomów znajduje się element, ale znasz jego zmienną / klasę / coś innego.
Graham

Odpowiedzi:


267

Ponieważ parent () zwraca elementy przodków uporządkowane od najbliższych do zewnętrznych, możesz połączyć je w eq () :

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

czy mogę użyć tego $ ('# element'). parent () [2]? albo musi minąć z eq (2)
Artur Keyan

1
to nie zadziała w przypadku wyboru wielu elementów, bezpieczniejszym sposobem byłoby:$('.element').first().parents().eq(num);
zzzzBov

6
@Arthur, użycie [2]zwróci podstawowy element DOM, użycie eq(2)zwróci obiekt jQuery.
Frédéric Hamidi

1
@zzzzBov, bardzo prawda, ale w przypadku pytającego zostanie wybrany tylko jeden element (ponieważ pasuje on do identyfikatora).
Frédéric Hamidi

Jeśli sprawdzisz identyfikator „#element”, zwróci to tylko jeden element, ponieważ tak działa wyszukiwanie identyfikatorów, zwracają pierwszy element z tym identyfikatorem w dom. Z drugiej strony, gdybyś zrobił "div # element" lub selektor klasy, miałbyś rację.
Henry

29

W zależności od Twoich potrzeb, jeśli wiesz, jakiego rodzica szukasz, możesz użyć selektora .parents ().

Np .: 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());

Przykład z użyciem indeksu:

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

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

Teraz tak, ale chcę podać poziom
Artur Keyan

3
Przeczytaj odpowiedź, a wszystko zostanie ujawnione! (Podałem przykłady poziomów)
Henry

Działa to dobrze dla wszystkich innych rodzajów selektorów. Na przykład, jeśli chcesz wyświetlić listę wszystkich rodziców i rodziców rodziców z określonej klasy, zwróci ich.
darksky

8

Możesz nadać docelowemu rodzicowi identyfikator lub klasę (np. MyParent) i odwołanie jest z $('#element').parents(".myParent")


Chcę podać tylko numer i uzyskać elementu, ponieważ mój element może nie mieć żadnego identyfikatora calss lub nazwę
Artur Keyan

6

Szybszym sposobem jest bezpośrednie użycie javascript, np.

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

Działa to znacznie szybciej w mojej przeglądarce niż łańcuchowe .parent()wywołania jQuery .

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


Mówiąc o „znacznie szybszym”, patrzymy na mniej więcej rząd wielkości pod względem różnicy szybkości (przy uruchomieniu jQuery 1.10.1 w Chrome 51). Zdecydowanie warto go wdrożyć, jeśli stawiasz na prędkość.
Iain Fraser,

5

Nie znalazłem żadnej odpowiedzi przy użyciu closest() i myślę, że jest to najprostsza odpowiedź, gdy nie wiesz, o ile poziomów wyżej jest wymagany element, więc opublikowanie odpowiedzi:
Możesz użyć closest()funkcji połączonej z selektorami, aby uzyskać pierwszy element, który pasuje przy przechodzeniu w górę od elementu:

('#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

To proste. Po prostu użyj

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

gdzie 0 to poziom nadrzędny (0 to rodzic, 1 to rodzic itp.)



3

Jeśli planujesz ponownie wykorzystać tę funkcjonalność, optymalnym rozwiązaniem jest stworzenie wtyczki jQuery:

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

Oczywiście możesz chcieć go rozszerzyć, aby umożliwić opcjonalny selektor i inne tego typu rzeczy.

Jedna uwaga: to używa 0indeksu opartego na rodzicach, więc nthParent(0)jest to to samo co dzwonienieparent() . Jeśli wolisz 1indeksowanie na podstawie, użyjn-- > 0


Myślę, że ta część znajdziesz szybciej: var p = 1 + n; while (p--) { $p = $p.parent(); }i JEŚLI chcesz zmienić na oparty na 1, Javascript jest „falsey”, możesz użyć: while (n--) { $p = $p.parent();} zapisanie czeku warunkowego
Mark Schultheiss

@Mark Schultheiss, Nie chodzi tylko o szybkość, ale także o niezawodność. Co się stanie z twoją funkcją, jeśli ktoś nieświadomie zadzwoni nthParent(-2)? Twój przykład jest zepsuty.
zzzzBov

LUB po prostu wróć(function($) { $.fn.nthParent = function(n) { return $(this).parents().eq(n); }; }(jQuery));
Mark Schultheiss

@Mark Schultheiss, znowu, niezawodność. Moja funkcja zwraca nthParent dla każdego elementu w selekcji, twoja funkcja zwraca n-ty element na liście, parentsktóry będzie niepoprawny dla selekcji z więcej niż jednym elementem.
zzzzBov

prawda w odniesieniu do -2, i jak w twoim przykładzie użycie var p = n >? (1 + n):1; zamiast tego zwróci w tym przypadku pierwszego rodzica zamiast „nic” - lub w miejscu, w którym przerywa pętlę w moim przykładzie. A więc prawdopodobnie powinno być: (function($) { $.fn.nthParent = function(n) { var $p = $(this); if (!(n > -0)) { return $() }; var p = 1 + n; while (p--) { $p = $p.parent(); } return $p; }; }(jQuery)); jeśli nie chcesz nic zwracać.
Mark Schultheiss

3

Jeśli mają wspólny div można użyć parentsUntil () odnośnik

na przykład: $('#element').parentsUntil('.commonClass')

Zaletą jest to, że nie musisz pamiętać, ile pokoleń istnieje między tym elementem a wspólnym rodzicem (zdefiniowanym przez commonclass).


1

możesz także użyć :

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

np .: $(this).ancestors().eq(2)-> rodzic rodzica this.


0

Możesz użyć czegoś takiego:

(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
Nie przeciwnik, ale jest to prawdopodobnie najgorsze rozwiązanie (tj. Nieefektywne) tutaj.
zatatatata

0

użycie eq wydaje się przechwytywać dynamiczny DOM, podczas gdy użycie .parent (). parent () wydaje się przechwytywać DOM, który został pierwotnie załadowany (jeśli to w ogóle możliwe).

Używam ich obu na elemencie, do którego zastosowano klasy w onmouseover. eq pokazuje klasy, podczas gdy .parent (). parent () nie.


Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.