Лучший способ узнать, является ли элемент потомком другого - PullRequest
63 голосов
/ 29 июня 2009

Я нахожусь в процессе реализации jQuery и извлечения библиотек Prototype из моей кодовой базы, и мне интересно, не могли бы вы дать мне лучший способ реализовать эту функциональность в jQuery. Я знаком с синтаксисом потомка jQuery > Потомок, но просто хочу проверить, является ли элемент потомком по true или false, как показано ниже: Кто-нибудь может дать мне наиболее эффективное решение jQuery для этого?

<div id="australopithecus">
  <div id="homo-herectus">
    <div id="homo-sapiens"></div>
  </div>
</div>

$('homo-sapiens').descendantOf('australopithecus');
// -> true

$('homo-herectus').descendantOf('homo-sapiens');
// -> false

Ответы [ 11 ]

107 голосов
/ 05 мая 2011

В jQuery 1.6 вы можете в общем случае использовать следующий код, например, targetElt и parentElt могут быть как элементами DOM, так и объектами в jQuery-оболочке, а также селекторами:

$(targetElt).closest(parentElt).length > 0

Для некоторых других ответов требуетсяВы должны ссылаться на элементы по их идентификаторам, что бесполезно, если у вас есть только элемент DOM без идентификатора.Кроме того, если вы хотите убедиться, что targetElt является строгим потомком parentElt (другими словами, вы не хотите считать parentElt своим собственным потомком), обязательно добавьте проверку targetElt != parentElt перед вызовом .closest(), или используйте .parents().find(), как предлагает Джонатан Сэмпсон.

42 голосов
/ 10 апреля 2013

С jQuery> = 1.4 (2010) вы можете использовать очень быструю функцию jQuery.contains ()

Этот статический метод работает с элементами DOM, а не с элементами jQuery и возвращает true или false.

jQuery.contains( container, descendant )

Пример: чтобы проверить, есть ли элемент в документе, вы можете сделать это:

jQuery.contains( document.body, myElement )

Обновление:

Существует также собственный метод DOM Node.contains () , который поддерживаются всеми браузерами начиная с ie5 +. Так что вы можете сделать это без jQuery:

document.body.contains( myElement )
31 голосов
/ 29 июня 2009

Я думаю, вы могли бы воспользоваться преимуществами выбора стиля CSS здесь с возвращенной длиной ..

$('#australopithecus #homo-sapiens').length // Should be 1
$('#homo-sapiens #homo-herectus').length // Should be 0

Не совсем верно / ложно, но проверка 0/1 как логического значения должна работать. :)

В качестве альтернативы вы можете сделать что-то вроде $ ('# parent'). Find ('# child') и проверить длину там.

21 голосов
/ 29 июня 2009

Как насчет


$("#homo-herectus").parents().is("#australopithecus");
5 голосов
/ 29 июня 2009

Вы можете использовать функцию is() следующим образом:

alert($('#homo-sapiens').is('#australopithecus *'));
// -> true

alert($('#homo-herectus').is('#homo-sapiens *'));
// -> false
4 голосов
/ 27 мая 2010
$.fn.descendantOf = function(element) {
    element = $(element)[0];
    var current = this;
    var body    = document.body;
    while (current && current != element && current != document.body) {
        current = $(current).parent()[0];
    }
    if (typeof(current) == "undefined" || typeof(current) == "null") {
        return false;
    } else if (current == element) {
        return true;
    } else if (current == document.body) {
        return false;
    }
}

Пример:

<div id="foo">
    <div id="bar">
        <div id="baz"></div>
    </div>
</div>

И

$('#foo').descendantOf('#bar');  // false
$('#foo').descendantOf('#foo');  // false
$('#foo').descendantOf(document.body);  // true
$('#bar').descendantOf('#foo');  // true
$('#baz').descendantOf('#foo');  // true
3 голосов
/ 29 июня 2009

Вы можете попытаться .find() это в Элементах .children()

$("#lucy").find("#homo-erectus").length;

Или в обратном направлении:

$("#homo-erectus").parents().find("#lucy").length;
2 голосов
/ 09 марта 2012

Лучший метод, который я нашел, это использование Дэна Г. Свитцера, метод II, найденный здесь http://blog.pengoworks.com/index.cfm/2008/9/24/Using-jQuery-to-determine-if-an-element-is-a-child-of-another-element

jQuery.fn.isChildOf = function(b){ 
    return (this.parents(b).length > 0); 
};

Тогда вы бы просто использовали плагин как:

$('homo-sapiens').isChildOf('australopithecus');
// -> true

$('homo-herectus').isChildOf('homo-sapiens');
// -> false
0 голосов
/ 02 ноября 2013

Альтернатива closest (), которая использует (почти) тот же принцип обхода и не включает сам элемент: child.parentsUntil(ancestor).last().parent().is(ancestor).

var child = $('#homo-sapiens');
var ancestor = $('#australopithecus');

console.log(child.parentsUntil(ancestor).last().parent().is(ancestor)); // true
0 голосов
/ 30 июня 2009

Предположим, переписать ваше первоначальное утверждение в:

$('#homo-sapiens').descendantOf('#australopithecus');

попробуйте подключить:

(function($) {
    $.fn.descendantOf = function(parentId) {
        return this.closest(parentId).length != 0;
    }
})(jQuery)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...