2009-06-29 4 views
60

Je suis en train d'implémenter jQuery et de sortir des librairies Prototype dans mon code, et je me demande si vous pourriez me donner le meilleur moyen d'implémenter cette fonctionnalité dans jQuery. Je suis familier avec la syntaxe descendant jQuery ancêtre >, mais je veux juste vérifier si un élément est un descendant par true de faux, comme le code ci-dessous: quelqu'un peut-il me donner la solution jQuery la plus efficace pour cela?Meilleur moyen de savoir si l'élément est un descendant d'un autre

<div id="australopithecus"> 
    <div id="homo-herectus"> 
    <div id="homo-sapiens"></div> 
    </div> 
</div> 

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

$('homo-herectus').descendantOf('homo-sapiens'); 
// -> false 
+2

duper: http://stackoverflow.com/questions/865486/how-can-i-check-if-an-element-is-within-another-one-in-jquery/865551 –

+4

Utiliser ' jQuery.contains() '. Voir ma réponse ci-dessous. – TLindig

Répondre

29

Je pense que vous pourriez profiter de la sélection de style CSS ici, avec la longueur de retour. Pas exactement vrai/faux, mais en vérifiant 0/1 comme un booléen devrait fonctionner. :)

Alternativement, vous pourriez faire quelque chose comme $ ('# parent'). Find ('# enfant') et vérifier la longueur là.

+1

merci pour toutes les bonnes réponses !! Je n'ai pas réalisé que j'avais tellement d'options :) – 29er

+1

Merci! Et vous pouvez les "convertir" en 'true' /' false' en ajoutant précédement '!!', comme '!! $ ('# australopithecus # homo-sapiens'). Length', qui retourne' true'. –

+0

Il n'est pas nécessaire de les convertir en quoi que ce soit d'autre puisque dans javascript false, 0, null et NaN sont tous comptés comme faux lorsqu'ils sont utilisés dans les instructions if ... –

3

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

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

Ou la direction opposée:

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

Je ne connais pas la syntaxe jQuery, mais il serait plus rapide de vérifier les parents() de l'objet descendant, plutôt que tous les enfants de l'ancêtre, non? – harpo

+0

@harpo, Potentiellement. En fonction des utilisateurs particuliers DOM. Bon conseil cependant - certainement quelque chose à considérer. – Sampson

21

Que diriez-vous


$("#homo-herectus").parents().is("#australopithecus"); 
-1
function descendantOf(parentId, childId) { 
    return ($('#'+parentId+' > #'+childId).length === 1); 
} 

Cela devrait fonctionner.

Comme il a été souligné dans le commentaire ci-dessous, si vous ne voulez pas qu'il soit juste descendants directs:

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

L'utilisation du caractère> dans le sélecteur limitera la vérification aux seuls décendeurs de première génération. Si vous voulez vérifier si c'est une sorte de descendant (par opposition à un descendant direct) alors supprimez simplement le caractère>. –

5

Vous pouvez utiliser la fonction is() comme ceci:

alert($('#homo-sapiens').is('#australopithecus *')); 
// -> true 

alert($('#homo-herectus').is('#homo-sapiens *')); 
// -> false 
+4

Ne pensez-vous pas que l'utilisation de * (astérisque) est trop chère, car elle vérifie tous les enfants sans s'arrêter lors du premier match? –

-1

Supposant de réécrire votre déclaration initiale:

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

essayer de plugin:

(function($) { 
    $.fn.descendantOf = function(parentId) { 
     return this.closest(parentId).length != 0; 
    } 
})(jQuery) 
4
$.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 :

<div id="foo"> 
    <div id="bar"> 
     <div id="baz"></div> 
    </div> 
</div> 

Et:

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

'typeof' n'est pas une fonction, c'est un mot-clé. Vous n'avez pas besoin de parenthèses, bien que ce soit toujours valide.'typeof courant ==" undefined "' – SeinopSys

103

Dans jQuery 1.6, vous pouvez utiliser génériquement le code suivant, par exemple targetElt et parentElt peuvent tous deux être des éléments DOM ou objets jQuery-emballés, ainsi que des sélecteurs:

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

Certains des autres réponses que vous besoin de se référer à des éléments par leur ID, ce qui est pas utile si vous ne disposez est un élément DOM sans ID.Aussi, si vous voulez vous assurer que le targetElt est un descendant strict de parentElt (en d'autres termes, vous ne voulez pas considérer parentElt comme son propre descendant), assurez-vous d'ajouter un targetElt != parentElt check avant votre appel au .closest(), ou utilisez .parents().find() comme le suggère Jonathan Sampson.

+3

Exactement ce que je voulais savoir, merci. –

+1

Cela devrait être la réponse acceptée. Toutes les autres réponses à cette question et le dup requièrent des identifiants/classes. Celui-ci est parfaitement transparent à tout cela –

+2

0 est falsey donc vous pouvez simplement utiliser $ (targetElt) .closest (parentElt) .length comme condition. (ie sans vérifier la longueur est> 0) – ensignr

2

Meilleure méthode que je trouve utilise Dan G. Switzer, la méthode II trouve ici: http://blog.pengoworks.com/index.cfm/2008/9/24/Using-jQuery-to-determine-if-an-element-is-a-child-of-another-element

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

Ensuite, vous utilisez simplement le plugin comme:

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

$('homo-herectus').isChildOf('homo-sapiens'); 
// -> false 
+1

Cela ne détermine qu'un seul niveau de descendance –

+0

@MildFuzz Je suis sûr que vous avez tort à ce sujet. 'parents()' traverse tout l'arbre pour chercher une correspondance. https://api.jquery.com/parents/ –

39

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

très rapide Cette méthode statique fonctionne avec des éléments DOM, et non avec des éléments jQuery une nd renvoie true ou false.

jQuery.contains(container, descendant) 

Exemple: Pour vérifier si un élément est dans le document que vous pourriez faire ceci:

jQuery.contains(document.body, myElement) 

Mise à jour:

Il y a aussi une méthode DOM natif Node.contains() que tous les navigateurs depuis ie5 + supports. Ainsi, vous pouvez le faire sans jQuery:

document.body.contains(myElement) 
+1

Ceci est la bonne réponse. – Andy

+0

Vous pouvez utiliser des objets jQuery en tirant l'élément DOM de l'objet en ajoutant "[0]" -> https://learn.jquery.com/using-jquery-core/faq/how-do-i-pull-a -native-dom-element-à partir d'un objet-jquery / –

0

Une alternative à la plus proche() qui utilise (presque) le même principe de déplacement et ne comprend 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 
Questions connexes