Compruebe si un elemento es hijo de un padre

115

tengo el siguiente 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 solo cuando Child-Of-Hellose $('div#hello').parents(target).lengthhaga clic en él, vuelva> 0.

Sin embargo, simplemente sucede cada vez que hago clic en cualquier lugar.

¿Hay algún problema con mi código?

Cheok Yan Cheng
fuente

Respuestas:

160

Si solo está interesado en el padre directo, y no en otros ancestros, puede usar parent()y darle el selector, como en target.parent('div#hello').

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

O si desea verificar si hay antepasados ​​que coincidan, utilice .parents().

Ejemplo: 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');
    }
}
usuario113716
fuente
19
¿cómo hacerlo sin jquery?
SuperUberDuper
60

.has()parece estar diseñado para este propósito. Dado que devuelve un objeto jQuery, también debe probar .length:

if ($('div#hello').has(target).length) {
   alert('Target is a child of #hello');
}
Blazemonger
fuente
@redanimalwar Derecha; eso es lo que hace esto. Encuentra el elemento padre, luego verifica si targetestá dentro de él.
Blazemonger
22

Vainilla 1 línea para IE8 +:

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

Aquí, cómo 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
fuente
¡Gracias, eso es bastante sorprendente! La recursividad es genial. Me pregunto cómo el argumento de la función se convierte (dentro) del objeto en el que opera la función. ¿Podría tener un enlace para obtener más información sobre eso?
JohnK
20

Si tiene un elemento que no tiene un selector específico y aún desea verificar si es descendiente de otro elemento, puede usar jQuery.contains ()

jQuery.contains (contenedor, contenido)
Descripción: Verifique si un elemento DOM es descendiente de otro elemento DOM.

Puede pasar el elemento padre y el elemento que desea verificar a esa función y devuelve si el último es descendiente del primero.

naitsirch
fuente
3
Preste especial atención a $.containstomar elementos DOM y no instancias de jQuery, o siempre devolverá falso.
aleclarson
Otro detalle para recordar: $.containsnunca devuelve verdadero si los dos argumentos son el mismo elemento. Si quieres eso, usa domElement.contains(domElement).
aleclarson
9

Terminó usando .closest () en su lugar.

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

Puede hacer que su código funcione simplemente intercambiando los dos términos:

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

Tuviste al niño y al padre al revés.

tttppp
fuente
2
var target = $(evt.target);por lo que su código debe leer if (target.parents('div#hello').length) {y no...$(target)...
Peter Ajtai
0

Además de las otras respuestas, puede usar este método menos conocido para tomar elementos de un determinado padre así,

$('child', 'parent');

En tu caso, eso sería

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

Tenga en cuenta el uso de comas entre el niño y el padre y sus comillas separadas. Si estuvieran rodeados por las mismas citas

$('child, parent');

tendría un objeto que contiene ambos objetos, independientemente de si existen en sus árboles de documentos.

Quiero respuestas
fuente
Este es un truco genial, pero no funciona bien con elementos sin identificadores o clases
aln447