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


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

11 ответов:

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

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

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

альтернативно, вы могли бы сделать что-то вроде $('#parent').найдите ('#child') и проверьте длину там.

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

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

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

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

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

jQuery.contains( container, descendant )

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

jQuery.contains( document.body, myElement )

обновление:

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

document.body.contains( myElement )

как о


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

можно использовать

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

вы могли бы попытаться .find() это в элементах .children()

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

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

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

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

альтернатива 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
function descendantOf(parentId, childId) {
   return ( $('#'+parentId+' > #'+childId).length === 1 );
}

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

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

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

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

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

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

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