Проверить, является ли элемент дочерним по отношению к родителю

115

У меня есть следующий код.

<html>
<head>
    <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js"></script>
</head>

<div id="hello">Hello <div>Child-Of-Hello</div></div>
<br />
<div id="goodbye">Goodbye <div>Child-Of-Goodbye</div></div>

<script type="text/javascript">
<!--
function fun(evt) {
    var target = $(evt.target);    
    if ($('div#hello').parents(target).length) {
        alert('Your clicked element is having div#hello as parent');
    }
}
$(document).bind('click', fun);
-->
</script>

</html>

Я ожидаю, что только при Child-Of-Helloнажатии $('div#hello').parents(target).lengthвернет> 0.

Однако это происходит всякий раз, когда я нажимаю где-нибудь.

Что-то не так с моим кодом?

Чеок Ян Ченг
источник

Ответы:

160

Если вас интересует только прямой родитель, а не другие предки, вы можете просто использовать parent()и дать ему селектор, как в target.parent('div#hello').

Пример: http://jsfiddle.net/6BX9n/

function fun(evt) {
    var target = $(evt.target);    
    if (target.parent('div#hello').length) {
        alert('Your clicked element is having div#hello as parent');
    }
}

Или, если вы хотите проверить, есть ли совпадающие предки, используйте .parents().

Пример: http://jsfiddle.net/6BX9n/1/

function fun(evt) {
    var target = $(evt.target);    
    if (target.parents('div#hello').length) {
        alert('Your clicked element is having div#hello as parent');
    }
}
user113716
источник
19
как это сделать без jquery?
SuperUberDuper
60

.has()похоже, предназначен для этой цели. Поскольку он возвращает объект jQuery, вам также необходимо проверить .length:

if ($('div#hello').has(target).length) {
   alert('Target is a child of #hello');
}
Blazemonger
источник
@redanimalwar Право; вот что это делает. Вы находите родительский элемент, затем проверяете, targetнаходится ли он внутри него.
Blazemonger
22

Ванильный однострочник для IE8 +:

parent !== child && parent.contains(child);

Вот как это работает:

function contains(parent, child) {
  return parent !== child && parent.contains(child);
}

var parentEl = document.querySelector('#parent'),
    childEl = document.querySelector('#child')
    
if (contains(parentEl, childEl)) {
  document.querySelector('#result').innerText = 'I confirm, that child is within parent el';
}

if (!contains(childEl, parentEl)) {
  document.querySelector('#result').innerText += ' and parent is not within child';
}
<div id="parent">
  <div>
    <table>
      <tr>
        <td><span id="child"></span></td>
      </tr>
    </table>
  </div>
</div>
<div id="result"></div>

Александр Маков
источник
Спасибо, это здорово! Рекурсия классная. Мне интересно, как аргумент функции становится (внутри) объектом, над которым работает функция. Не могли бы вы дать ссылку на дополнительную информацию по этому поводу?
JohnK
20

Если у вас есть элемент, у которого нет определенного селектора, и вы все еще хотите проверить, является ли он потомком другого элемента, вы можете использовать jQuery.contains ()

jQuery.contains (контейнер, содержащийся)
Описание: проверьте, является ли элемент DOM потомком другого элемента DOM.

Вы можете передать родительский элемент и элемент, который вы хотите проверить, этой функции, и она вернется, если последний является потомком первого.

Naitsirch
источник
3
Обратите особое внимание на $.containsиспользование элементов DOM, а не экземпляров jQuery, иначе он всегда будет возвращать false.
aleclarson
Еще одна деталь, которую следует запомнить: $.containsникогда не возвращает истину, если два аргумента являются одним и тем же элементом. Если вы этого хотите, используйте domElement.contains(domElement).
aleclarson
9

Вместо этого мы использовали .closest ().

$(document).on("click", function (event) {
    if($(event.target).closest(".CustomControllerMainDiv").length == 1)
    alert('element is a child of the custom controller')
});
Lukas
источник
3

Вы можете заставить свой код работать, просто поменяв местами два термина:

if ($(target).parents('div#hello').length) {

У вас неправильный путь к ребенку и родителю.

tttppp
источник
2
var target = $(evt.target);так что ваш код должен читаться, if (target.parents('div#hello').length) {а не...$(target)...
Питер Аджтай
0

В дополнение к другим ответам вы можете использовать этот менее известный метод для захвата элементов определенного родителя, например, так,

$('child', 'parent');

В вашем случае это было бы

if ($(event.target, 'div#hello')[0]) console.log(`${event.target.tagName} is an offspring of div#hello`);

Обратите внимание на использование запятых между дочерним и родительским элементом и их отдельные кавычки. Если бы они были окружены одинаковыми кавычками

$('child, parent');

у вас будет объект, содержащий оба объекта, независимо от того, существуют ли они в их деревьях документов.

Я хочу ответы
источник
Это крутой хак, но он плохо работает с элементами без идентификаторов или классов
aln447 09