Meilleur moyen de savoir si l’élément est un descendant d’un autre

Je suis en train d’implémenter jQuery et de sortir des bibliothèques Prototype dans mon code, et je me demande si vous pourriez me donner le meilleur moyen d’implémenter cette fonctionnalité dans jQuery. Je connais bien la syntaxe descendante jQuery ancestor > , mais je veux juste vérifier si un élément est un descendant par true ou false, comme le code ci-dessous: quelqu’un peut-il me donner la solution jQuery la plus efficace pour cela?

 
$('homo-sapiens').descendantOf('australopithecus'); // -> true $('homo-herectus').descendantOf('homo-sapiens'); // -> false

Je pense que vous pouvez tirer parti de la sélection de style CSS ici, avec la longueur renvoyée.

 $('#australopithecus #homo-sapiens').length // Should be 1 $('#homo-sapiens #homo-herectus').length // Should be 0 

Pas exactement vrai / faux, mais vérifier 0/1 comme un booléen devrait fonctionner. 🙂

Sinon, vous pouvez faire quelque chose comme $ (‘# parent’). Find (‘# child’) et vérifier la longueur.

Dans jQuery 1.6, vous pouvez utiliser le code suivant de manière générique, par exemple targetElt et parentElt peuvent tous deux être des éléments DOM ou des objects enveloppés avec jQuery, ainsi que des sélecteurs:

 $(targetElt).closest(parentElt).length > 0 

Certaines des autres réponses nécessitent que vous vous référiez à des éléments par leurs identifiants, ce qui n’est pas utile si vous n’avez qu’un élément DOM sans identifiant. De plus, si vous voulez vous assurer que targetElt est un descendant ssortingct de parentElt (en d’autres termes, vous ne voulez pas compter parentElt comme son propre descendant), assurez-vous d’append un targetElt != parentElt avant votre appel à .closest() , ou utilisez .parents().find() comme le suggère Jonathan Sampson.

Avec jQuery> = 1.4 (2010), vous pouvez utiliser la fonction très rapide jQuery.contains ()

Cette méthode statique fonctionne avec des éléments DOM, pas avec des éléments jQuery et renvoie true ou false .

 jQuery.contains( container, descendant ) 

Exemple: Pour vérifier si un élément est dans le document, vous pouvez le faire:

 jQuery.contains( document.body, myElement ) 

Mettre à jour:

Il existe également une méthode DOM native Node.contains () prise en charge par tous les navigateurs depuis la version 5 +. Donc, vous pouvez le faire sans jQuery:

 document.body.contains( myElement ) 

Que diriez-vous

 $("#homo-herectus").parents().is("#australopithecus"); 

Vous pouvez utiliser la fonction is() comme suit:

 alert($('#homo-sapiens').is('#australopithecus *')); // -> true alert($('#homo-herectus').is('#homo-sapiens *')); // -> false 
 $.fn.descendantOf = function(element) { element = $(element)[0]; var current = this; var body = document.body; while (current && current != element && current != document.body) { current = $(current).parent()[0]; } if (typeof(current) == "undefined" || typeof(current) == "null") { return false; } else if (current == element) { return true; } else if (current == document.body) { return false; } } 

Exemple:

 

Et:

 $('#foo').descendantOf('#bar'); // false $('#foo').descendantOf('#foo'); // false $('#foo').descendantOf(document.body); // true $('#bar').descendantOf('#foo'); // true $('#baz').descendantOf('#foo'); // true 

Vous pouvez essayer de le .find() dans les éléments .children()

 $("#lucy").find("#homo-erectus").length; 

Ou la direction opposée:

 $("#homo-erectus").parents().find("#lucy").length; 

La meilleure méthode que j’ai trouvée est d’utiliser la méthode de Dan G. Switzer, II trouvée ici: http://blog.pengoworks.com/index.cfm/2008/9/24/Using-jQuery-to-determine-if-an-element -est-un-enfant-d’un-autre-élément

 jQuery.fn.isChildOf = function(b){ return (this.parents(b).length > 0); }; 

Ensuite, vous utiliseriez simplement le plugin comme:

 $('homo-sapiens').isChildOf('australopithecus'); // -> true $('homo-herectus').isChildOf('homo-sapiens'); // -> false 

Une alternative à close () qui utilise (presque) le même principe de child.parentsUntil(ancestor).last().parent().is(ancestor) et n’inclut pas l’élément lui-même: child.parentsUntil(ancestor).last().parent().is(ancestor) .

 var child = $('#homo-sapiens'); var ancestor = $('#australopithecus'); console.log(child.parentsUntil(ancestor).last().parent().is(ancestor)); // true 
 function descendantOf(parentId, childId) { return ( $('#'+parentId+' > #'+childId).length === 1 ); } 

Cela devrait fonctionner.

Comme indiqué dans le commentaire ci-dessous, si vous ne voulez pas que ce soit juste des descendants directs:

 function descendantOf(parentId, childId) { return ( $('#'+childId, $('#'+parentId)).length === 1 ); } 

En supposant de réécrire votre déclaration initiale en:

 $('#homo-sapiens').descendantOf('#australopithecus'); 

essayez de twigr:

 (function($) { $.fn.descendantOf = function(parentId) { return this.closest(parentId).length != 0; } })(jQuery)