Sprawdź, czy element jest dzieckiem rodzica

115

Mam następujący kod.

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

Spodziewam się, że tylko po Child-Of-Hellokliknięciu $('div#hello').parents(target).lengthzwróci> 0.

Jednak dzieje się tak po prostu za każdym razem, gdy kliknę w dowolnym miejscu.

Czy coś jest nie tak z moim kodem?

Cheok Yan Cheng
źródło

Odpowiedzi:

160

Jeśli interesuje Cię tylko bezpośredni rodzic, a nie inni przodkowie, możesz po prostu użyć parent()i nadać mu selektor, jak w target.parent('div#hello').

Przykład: 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');
    }
}

Lub jeśli chcesz sprawdzić, czy są jacyś zgodni przodkowie, użyj .parents().

Przykład: 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
źródło
19
jak to zrobić bez jQuery?
SuperUberDuper
60

.has()wydaje się być przeznaczony do tego celu. Ponieważ zwraca obiekt jQuery, musisz również przetestować .length:

if ($('div#hello').has(target).length) {
   alert('Target is a child of #hello');
}
Blazemonger
źródło
@redanimalwar Right; to właśnie robi. Znajdź element nadrzędny, a następnie sprawdź, czy targetjest w nim.
Blazemonger
22

Vanilla 1-liner dla IE8 +:

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

Oto jak to działa:

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>

Aleksandr Makov
źródło
Dzięki, to niesamowite! Rekursja jest fajna. Zastanawiam się, jak argument funkcji staje się (wewnątrz) obiektem, na którym działa funkcja. Czy możesz mieć link do dodatkowych informacji na ten temat?
JohnK
20

Jeśli masz element, który nie ma określonego selektora i nadal chcesz sprawdzić, czy jest potomkiem innego elementu, możesz użyć jQuery.contains ()

jQuery.contains (kontener, zawarty)
Opis: sprawdź, czy element DOM jest potomkiem innego elementu DOM.

Możesz przekazać element nadrzędny i element, który chcesz sprawdzić, do tej funkcji i zwraca ona, jeśli ten drugi jest potomkiem pierwszego.

naitsirch
źródło
3
Zwróć szczególną uwagę na $.containspobieranie elementów DOM, a nie instancji jQuery, w przeciwnym razie zawsze zwróci false.
aleclarson,
Kolejny szczegół do zapamiętania: $.containsnigdy nie zwraca prawdy, jeśli dwa argumenty są tym samym elementem. Jeśli chcesz, użyj domElement.contains(domElement).
aleclarson,
9

Skończyło się na użyciu .closest () zamiast.

$(document).on("click", function (event) {
    if($(event.target).closest(".CustomControllerMainDiv").length == 1)
    alert('element is a child of the custom controller')
});
Lukas
źródło
3

Aby kod działał, wystarczy zamienić dwa terminy:

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

Zabrałeś dziecko i rodzica w niewłaściwy sposób.

tttppp
źródło
2
var target = $(evt.target);więc twój kod powinien czytać, if (target.parents('div#hello').length) {a nie...$(target)...
Peter Ajtai
0

Oprócz innych odpowiedzi możesz użyć tej mniej znanej metody, aby pobrać elementy określonego rodzica, takie jak:

$('child', 'parent');

W twoim przypadku tak by było

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

Zwróć uwagę na użycie przecinków między dzieckiem a rodzicem oraz ich oddzielnymi cudzysłowami. Gdyby były otoczone tymi samymi cudzysłowami

$('child, parent');

miałbyś obiekt zawierający oba obiekty, niezależnie od tego, czy istnieją one w ich drzewach dokumentów.

Chcę odpowiedzi
źródło
To fajny hack, ale nie działa dobrze z elementami bez identyfikatorów lub klas
aln447