2010-10-14 4 views
2

Possible en double:
jQuery filtering selector to remove nested elements matching pattern.jQuery - classe select ne figure pas dans une autre classe

J'ai une hiérarchie de groupes. Quelque chose comme:

<div class="group"> 
    <span class="child"></span> 
    <div class="group"> 
     <span class="child"></span> 
     <span class="child"></span> 
     <span class="child"></span> 
    </div> 
    <span class="child"></span> 
    <span class="child"></span> 
    <div>This child is farther down <span class="child"></span></div> 
</div> 

Comment puis-je sélectionner les enfants dans chaque groupe, sans sélectionner les enfants d'un sous-groupe?

$(".group").each(function() { 
    // Wrong, click fires twice (the 1st level group selects 2nd level children) 
    var children = $(this).children(".child"); 

    // Wrong, click fires twice 
    children = $(this).children(":not(.group) .child"); 

    // How can I properly do this?? 

    children.click(function() { 
     alert("children.click"); 
    }); 
}); 

J'ai aussi essayé find() au lieu de children(), mais je ne peux pas sembler que cela fonctionne correctement. De même, je ne peux pas utiliser d'enfants directs (ou >) car les descendants pourraient se trouver à l'intérieur d'autres balises HTML non-.gorup (c'est-à-dire, plusieurs niveaux DOM).

+2

Mmmh j'ai essayé dans jsFiddle et le clic est pas tiré deux fois .. Mais quoi qu'il en soit, vous pouvez utiliser 'event.stopPropagation()' pour empêcher l'événement de bouillonner. –

+0

Que voulez-vous dire que les enfants peuvent être plusieurs couches vers le bas? Quelle que soit la structure, .group> .child récupère les groupements dont vous avez besoin en fonction de la disposition DOM. –

+0

Enfants! = Descendants. * Les enfants * ne peuvent être qu'une seule couche vers le bas ... –

Répondre

1

Si .child est toujours un descendant direct de son groupe, alors le sélecteur > fonctionnera, comme indiqué. Sinon, vous pouvez filtrer défini avec une fonction

var group = this; 
$(group).find('.child').filter(function() { 
    // check if current element belongs to our group 
    return $(this).closest('.group')[0] == group; 
}) 

An example

+0

Je pense à la fois gnarf et vous avez raison. Je pense que le vôtre serait plus rapide car il n'a qu'à remonter l'arbre à quelques nœuds, mais il doit le faire pour chaque enfant donc je ne suis pas complètement sûr. C'est une version plus proche de ce que je cherchais: http://jsfiddle.net/KxnTZ/2/ –

+0

@Nelson Version avec _not_ traite également tous les enfants, donc je pense qu'ils devraient avoir des vitesses comparables. Bien que cela dépende de l'efficacité de la substruction des ensembles dans jquery: si _a.not (b) _ signifie que chaque élément de _a_ est comparé à chaque élément de _b_, ce serait mauvais. –

+0

Donc, mon vrai problème était en fait j'avais besoin de sélectionner une case à cocher dans la durée. J'ai donc quelque chose de comparable à '$ (groupe) .find (". Child "). Filter (...). Find (": checkbox ")'.Bien sûr, cette dernière trouvaille n'est pas restée dans les limites puisque nous avions déjà filtré auparavant. Votre exemple (qui a fonctionné) m'a aidé à trouver cette erreur. –

1

Si vous voulez que les enfants directs d'un groupe, vous pouvez essayer quelque chose comme:

$('.group > .child').click(function(){ 
    alert('You clicked on: '+$(this).text()); 
}); 

documentation Voir à jQuery: child-selector

EDIT: sinon vous pouvez consulter le duplicate question publié par Gnarf

+0

J'ai ajouté quelques informations supplémentaires que vous avez peut-être manqué. Les enfants peuvent être à l'intérieur d'autres balises HTML non-groupe. –

0

Essayez cela, il est également très lisible:

$(".group").each(function() { 
    var allChilds = $(this).find('.child'); 
    var subChilds = $(this).find('.group .child'); 

    var firstChilds = allChilds.not(subChilds); 
    firstChilds.css({ color: 'red' }); 
}); 
Questions connexes