Як отримати батьківський елемент елемента n-го рівня в jQuery?


151

Коли я хочу отримати, наприклад, батько 3-го рівня елемента, який я повинен написати, $('#element').parent().parent().parent()чи є для цього більш оптимальний метод?


2
Я хочу надати лише число (Level) та отримати елемент, оскільки мій елемент може не мати жодного ідентифікатора або імені
calss

1
Якщо ви плануєте повторно використовувати цю функціональність, оптимальним рішенням буде зробити плагін jQuery.
zzzzBov

3
Дивіться на jsperf.com/jquery-get-3rd-level-parent для деяких порівнянь продуктивності
1111

1
Ще одним хорошим інструментом є функція ".closest ()". $ ('li.item'). Найближчий ('div') дасть вам DIV, який є найближчим предком li.item. Добре, коли ви не знаєте, на скільки рівнів знаходиться елемент, але ви знаєте його тег / клас / щось інше.
Грем

Відповіді:


267

Оскільки батьки () повертають впорядковані предки елементи з найближчих до зовнішніх, ви можете ланцюжок в eq () :

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

Чи можу я використовувати цей $ ('# елемент'). батьків () [2]? або це повинно бути з eq (2)
Артур Кеян

1
це не працюватиме для вибору декількох елементів, більш безпечним способом буде:$('.element').first().parents().eq(num);
zzzzBov

6
@Arthur, використовуючи [2]поверне базовий елемент DOM, використовуючи eq(2)поверне об'єкт jQuery.
Фредерік Хаміді

1
@zzzzBov, дуже правда, але у випадку запитувача буде обраний лише один елемент (бо він відповідає ідентифікатору).
Фредерік Хаміді

Якщо ви подивитеся на id "#element", він поверне лише один елемент, оскільки так працює пошук ID, вони повертають перший елемент із цим ідентифікатором у dom. Якщо ви, з іншого боку, зробили "елемент # елемент" або вибір класу, ви б мали рацію.
Генріх

29

Залежить від ваших потреб, якщо ви знаєте, якого з батьків шукаєте, ви можете скористатися перемикачем .parents ().

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());

Приклад з використанням індексу:

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

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

Я зараз таким чином, але хочу дати рівень
Артур Кеян

3
Прочитайте далі відповідь, і все виявиться! (Я наводив вам приклади рівня)
Генрі

Це добре працює для всіх інших видів селекторів. Наприклад, якщо ви хочете список усіх батьків та батьків батьків з певним класом, це поверне їх.
темний

8

Ви можете дати цільовому батькові ідентифікатор або клас (наприклад, myParent) і посилання на $('#element').parents(".myParent")


Я хочу вказати лише число та отримати елемент, оскільки мій елемент може не мати жодного ідентифікатора або імені
calss

6

Більш швидкий спосіб - безпосередньо використовувати javascript, наприклад.

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

У моєму браузері це працює значно швидше, ніж ланцюжок .parent()дзвінків jQuery .

Дивіться: http://jsperf.com/jquery-get-3rd-level-parent


Під «значно швидше» ми розглядаємо приблизно порядок з точки зору різниці швидкостей (працює jQuery 1.10.1 на Chrome 51). Безумовно, варто застосувати, якщо ви налаштовуєте на швидкість.
Iain Fraser

5

Не знайшов жодної відповіді, closest() і я думаю, що це найпростіша відповідь, коли ви не знаєте, на скільки рівнів потрібний елемент, тому розміщуючи відповідь:
Ви можете використовувати closest()функцію в поєднанні з селекторами, щоб отримати перший елемент, який відповідає при переході вгору від елемента:

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

Це просто. Просто використовуйте

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

де 0 - батьківський рівень (0 - батьківський, 1 - батьківський і т.д. тощо)


3

Просто додайте :eq()селектор так:

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

Ви просто вказуєте індекс, який з батьків: 0 для безпосереднього батька, 1 для онука, ...


Цей спосіб - найшвидший спосіб зробити роботу. Ось орієнтир, щоб довести це: jsperf.com/jquery-get-element-s-nth-parent
java-man-script

3

Якщо ви плануєте повторно використовувати цю функціональність, оптимальним рішенням буде зробити плагін jQuery:

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

Звичайно, ви можете розширити його, щоб дозволити додатковий вибір та інші подібні речі.

Одне зауваження: для цього використовується 0індекс для батьків, тому nthParent(0)це те саме, що дзвонити parent(). Якщо ви хочете 1базувати індексацію, скористайтесяn-- > 0


Я думаю, що ви знайдете цю частину швидше: var p = 1 + n; while (p--) { $p = $p.parent(); }і якщо ви хочете змінити на 1 базу, Javascript - "фальси", ви можете використовувати: while (n--) { $p = $p.parent();} збереження умовного чека
Марк Шультхейс

@Mark Schultheiss, Справа не лише в швидкості, а й у надійності. Що відбувається з вашою функцією, якщо хтось необізнано дзвонить nthParent(-2)? Ваш приклад зламаний.
zzzzBov

АБО просто повернемось(function($) { $.fn.nthParent = function(n) { return $(this).parents().eq(n); }; }(jQuery));
Марк Шультейс

@ Марк Шультейс, знову ж таки, надійність. Моя функція повертає nthParent для кожного елемента у виділенні, ваша функція повертає n-й елемент, у списку parentsякого буде неправильним для виділень з більш ніж одним елементом.
zzzzBov

вірно щодо -2, і, як у вашому прикладі, використовуючи var p = n >? (1 + n):1; натомість, повертається перший батьківський випадок у цьому випадку, а не "нічого" - або там, де він порушує цикл у моєму прикладі. Так, мабуть, так і повинно бути: (function($) { $.fn.nthParent = function(n) { var $p = $(this); if (!(n > -0)) { return $() }; var p = 1 + n; while (p--) { $p = $p.parent(); } return $p; }; }(jQuery)); якщо ви нічого не хочете повернути.
Марк Шультейс

3

Якщо у вас є спільний родительський розділ, ви можете скористатися посиланням parentUntil ()

наприклад: $('#element').parentsUntil('.commonClass')

Перевага полягає в тому, що вам не потрібно пам’ятати, скільки поколінь існує між цим елементом і загальним батьківським (визначеним загальним класом).


1

Ви також можете використовувати:

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

наприклад: $(this).ancestors().eq(2)-> батьків батьків this.


0

Ви можете використовувати щось подібне:

(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
Це не знижувач, але це, мабуть, найгірше рішення (тобто неефективне) тут.
зататата

0

З допомогою eq з'являється, щоб схопити динамічний DOM, тоді як за допомогою .parent (). parent (), схоже, схопити DOM, який був завантажений спочатку (якщо це навіть можливо).

Я використовую їх як на елементі, який має класи, застосовані до цього onmouseover. eq показує класи, а .parent (). parent () doesnt.


Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.