Verifique se um elemento é filho de um pai

115

Eu tenho o seguinte código.

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

Espero que apenas quando Child-Of-Hellofor clicado, $('div#hello').parents(target).lengthretornará> 0.

No entanto, isso acontece sempre que clico em qualquer lugar.

Há algo errado com meu código?

Cheok Yan Cheng
fonte

Respostas:

160

Se você estiver interessado apenas no pai direto, e não em outros ancestrais, pode simplesmente usar parent()e fornecer o seletor, como em target.parent('div#hello').

Exemplo: 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');
    }
}

Ou se quiser verificar se há ancestrais que correspondam, use .parents().

Exemplo: 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
fonte
19
como fazer isso sem jquery?
SuperUberDuper
60

.has()parece ter sido projetado para esse fim. Como ele retorna um objeto jQuery, você também deve testar .length:

if ($('div#hello').has(target).length) {
   alert('Target is a child of #hello');
}
Blazemonger
fonte
@redanimalwar Right; é isso que isso faz. Você encontra o elemento pai e verifica se targetestá dentro dele.
Blazemonger
22

Vanilla 1-liner para IE8 +:

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

Veja como funciona:

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
fonte
Obrigado, isso é incrível! A recursão é legal. Estou me perguntando como o argumento da função se torna (dentro) o objeto em que a função opera. Você poderia ter um link para mais informações sobre isso?
JohnK
20

Se você tem um elemento que não tem um seletor específico e ainda deseja verificar se é descendente de outro elemento, você pode usar jQuery.contains ()

jQuery.contains (container, contido)
Descrição: Verifique se um elemento DOM é descendente de outro elemento DOM.

Você pode passar o elemento pai e o elemento que deseja verificar para essa função e ela retorna se o último for um descendente do primeiro.

Naitsirch
fonte
3
Preste atenção extra em $.containspegar elementos DOM e não instâncias jQuery, ou sempre retornará falso.
aleclarson
Outro detalhe a lembrar: $.containsnunca retorna verdadeiro se os dois argumentos são o mesmo elemento. Se você quiser isso, use domElement.contains(domElement).
aleclarson de
9

Acabou usando .closest ().

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

Você pode fazer seu código funcionar apenas trocando os dois termos:

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

Você enganou o filho e o pai.

tttppp
fonte
2
var target = $(evt.target);portanto, seu código deve ser lido if (target.parents('div#hello').length) {e não...$(target)...
Peter Ajtai,
0

Além das outras respostas, você pode usar este método menos conhecido para obter elementos de um determinado pai, como assim,

$('child', 'parent');

No seu caso, isso seria

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

Observe o uso de vírgulas entre a criança e os pais e suas aspas separadas. Se eles estivessem entre as mesmas citações

$('child, parent');

você teria um objeto contendo ambos os objetos, independentemente de eles existirem em suas árvores de documentos.

Eu quero respostas
fonte
Este é um hack legal, mas não funciona bem com elementos sem ids ou classes
aln447