Vérifier si un élément est un enfant d'un parent

115

J'ai le code suivant.

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

J'attends que lorsque vous Child-Of-Hellocliquez dessus, $('div#hello').parents(target).lengthretournera> 0.

Cependant, cela arrive quand je clique n'importe où.

Y a-t-il un problème avec mon code?

Cheok Yan Cheng
la source

Réponses:

160

Si vous n'êtes intéressé que par le parent direct, et non par les autres ancêtres, vous pouvez simplement utiliser parent()et lui donner le sélecteur, comme dans target.parent('div#hello').

Exemple: 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 si vous voulez vérifier s'il existe des ancêtres qui correspondent, utilisez .parents().

Exemple: 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');
    }
}
utilisateur113716
la source
19
comment faire sans jquery?
SuperUberDuper
60

.has()semble être conçu à cet effet. Puisqu'il renvoie un objet jQuery, vous devez également tester .length:

if ($('div#hello').has(target).length) {
   alert('Target is a child of #hello');
}
Blazemonger
la source
@redanimalwar Droite; c'est ce que cela fait. Vous trouvez l'élément parent, puis vérifiez s'il se targettrouve à l'intérieur.
Blazemonger
22

Vanilla 1-liner pour IE8 +:

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

Voici comment ça marche:

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
la source
Merci, c'est assez incroyable! La récursion est cool. Je me demande comment l'argument de la fonction devient (à l'intérieur) l'objet sur lequel la fonction opère. Pourriez-vous avoir un lien vers plus d'informations à ce sujet?
JohnK
20

Si vous avez un élément qui n'a pas de sélecteur spécifique et que vous voulez quand même vérifier s'il est un descendant d'un autre élément, vous pouvez utiliser jQuery.contains ()

jQuery.contains (conteneur, contenu)
Description: Vérifiez si un élément DOM est un descendant d'un autre élément DOM.

Vous pouvez passer l'élément parent et l'élément que vous souhaitez vérifier à cette fonction et elle retourne si ce dernier est un descendant du premier.

naitsirch
la source
3
Faites particulièrement attention à la $.containsprise d'éléments DOM et non d' instances jQuery, sinon il retournera toujours false.
aleclarson
Autre détail à retenir: $.containsne renvoie jamais vrai si les deux arguments sont le même élément. Si vous le souhaitez, utilisez domElement.contains(domElement).
aleclarson
9

J'ai fini par utiliser .closest () à la place.

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

Vous pouvez faire fonctionner votre code en échangeant simplement les deux termes:

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

Vous avez fait tourner l'enfant et le parent dans le mauvais sens.

tttppp
la source
2
var target = $(evt.target);donc votre code doit lire if (target.parents('div#hello').length) {et non...$(target)...
Peter Ajtai
0

En plus des autres réponses, vous pouvez utiliser cette méthode moins connue pour récupérer les éléments d'un certain parent comme ça,

$('child', 'parent');

Dans votre cas, ce serait

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

Notez l'utilisation de virgules entre l'enfant et le parent et leurs guillemets séparés. S'ils étaient entourés des mêmes citations

$('child, parent');

vous auriez un objet contenant les deux objets, qu'ils existent ou non dans leurs arborescences de documents.

Je veux des réponses
la source
C'est un hack sympa, mais ne fonctionne pas bien avec des éléments sans identifiants ni classes
aln447