Лучший способ узнать, является ли элемент потомком другого

Я занимаюсь внедрением jQuery и вынимаю библиотеки Prototype в моей кодовой базе, и мне интересно, можете ли вы дать мне лучший способ реализовать эту функцию в jQuery. Я знаком с синтаксисом потомка jQuery ancestor >, но просто хочу проверить, является ли элемент потомком истинным значением 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

Ответ 1

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

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

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

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

Ответ 2

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

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

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

Ответ 3

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

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

jQuery.contains( container, descendant )

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

jQuery.contains( document.body, myElement )

Update:

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

document.body.contains( myElement )

Ответ 4

Как насчет


$("#homo-herectus").parents().is("#australopithecus");

Ответ 5

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

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

alert($('#homo-herectus').is('#homo-sapiens *'));
// -> false

Ответ 6

$.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

Ответ 7

Вы можете попробовать .find() в элементе .children()

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

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

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

Ответ 8

Лучший метод, который я нашел, - это использование метода Dan G. Switzer, 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

Ответ 9

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

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

console.log(child.parentsUntil(ancestor).last().parent().is(ancestor)); // true

Ответ 10

function descendantOf(parentId, childId) {
   return ( $('#'+parentId+' > #'+childId).length === 1 );
}

Это должно работать.

Как было указано в комментарии ниже, если вы не хотите, чтобы это были просто прямые потомки:

function descendantOf(parentId, childId) {
   return ( $('#'+childId, $('#'+parentId)).length === 1 );
}

Ответ 11

Предположим переписать исходный оператор в:

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

попробуйте плагин:

(function($) {
    $.fn.descendantOf = function(parentId) {
        return this.closest(parentId).length != 0;
    }
})(jQuery)