2009-06-04 8 views
3

J'ai essayé de résoudre ce problème, mais je n'arrive pas à le résoudre sans certaines solutions de contournement sérieuses.jquery prochaine frères et sœurs

si j'ai le code HTML suivant:

<ul> 
    <li class="parent"> headertext </li> 
    <li> text </li> 
    <li> text </li> 
    <li> text </li> 
    <li class="parent"> headertext </li> 
    <li> text </li> 
    <li> text </li> 
</ul> 

Maintenant, comment puis-je maintenant il suffit de sélectionner les balises suivantes <li> le premier parent (ou deuxième, pour cette question)? Fondamentalement en sélectionnant un <li> avec class="parent" et les frères et sœurs suivants jusqu'à ce qu'il atteigne un autre <li> avec la classe parente.

Je pourrais restructurer la liste avec des listes imbriquées, mais je ne veux pas faire cela. Aucune suggestion?

Répondre

6

La racine de votre problème est que les <li> s que vous avez classés en tant que parent ne sont vraiment pas les parents du <li> s « ci-dessous » eux. Ils sont frères et sœurs. jQuery a beaucoup, beaucoup de fonctions qui fonctionnent avec les parents réels. Je suggère de réparer votre balisage, vraiment. Ce serait plus rapide, plus propre, plus facile à maintenir, et plus sémantiquement correct que d'utiliser jQuery pour paver quelque chose ensemble.

+0

Je suis d'accord avec cela, cependant, j'ai posté un solution potentielle. Ce serait beaucoup plus facile si les relations DOM correspondaient aux relations réelles. – tvanfosson

+0

ouais, en fait, j'ai pensé que le nom de classe "parent" était un peu faux après que je l'ai posté. l'appeler "en-tête" pourrait être mieux. Je pourrais avoir à utiliser des listes imbriquées après tout – Contra

+0

Je pense qu'à long terme c'est la meilleure approche. Je sais que vous ne voulez pas le refaire maintenant, mais vous pouvez vous remercier plus tard. –

0
$("li.parent ~ li"); 
+0

$ ("li.parent ~ li: not (li.parent)"); <<<<< cela laissera le prochain class = "parent" s. Il ne s'arrête pas à ce point cependant .... – Ropstah

+0

ouais je viens d'écrire exactement le même code, mais comme vous l'avez mentionné, il ne s'arrête pas quand il atteint la classe suivante = parent – Contra

2

Je ne pense pas qu'il y ait un moyen de faire cela sans utiliser chacun puisque tous les autres sélecteurs sélectionneront également le deuxième parent et ses frères et sœurs suivants.

function getSibs(elem) { 
    var sibs = []; 
    $(elem).nextAll().each(function() { 
     if (!$(this).hasClass('parent')) { 
      sibs.push(this); 
     } 
     else { 
      return false; 
     } 
    }); 
    return $(sibs); 
} 
+0

* frissonne * Bonne idée, mais bon sang, je détesterais l'utiliser moi-même. :) –

+0

haha, en fait, c'est très proche de la solution de contournement im en utilisant atm :) * honte * – Contra

1

Vous devrez exécuter la boucle vous-même car jQuery ne sait pas s'arrêter à une condition spécifique.

jQuery.fn.nextUntil = function(selector) 
{ 
    var query = jQuery([]); 
    while(true) 
    { 
     var next = this.next(); 
     if(next.length == 0 || next.is(selector)) 
     { 
      return query; 
     } 
     query.add(next); 
    } 
    return query; 
} 

// To retrieve all LIs avec a parent 
$(".parent:first").nextUntil(".parent"); 

mais vous pouvez mieux utiliser une liste vraiment structurée pour vos parents/enfants relation

<ul> 
<li class="parent"> <span>headertext</span> 
    <ul> 
    <li> text </li> 
    <li> text </li> 
    <li> text </li> 
    </ul> 
</li> 
<li class="parent"> <span>headertext</span> 
    <ul> 
    <li> text </li> 
    <li> text </li> 
    </ul> 
</li> 
</ul> 
+0

Oui, je me suis rendu compte maintenant que c'est plus propre. Aussi beaucoup plus facile de travailler avec, comme quelqu'un l'a mentionné. Je pensais juste qu'il y avait une certaine magie de sélection que je ne pouvais pas comprendre, mais il semble que ce n'est pas possible sans manipuler le tableau après. – Contra

0
<html> 
    <head> 
     <script type="text/javascript"> 
      $(document).ready(function() { 
       $("a").click(function() { 
        var fred = $("li").not('.parent').text(); 
        $('#result').text(fred);   
       }); 
      });   
     </script> 
    </head> 
    <body> 
     <a href="#">Click me</a> 
     <ul> 
      <li class="parent"> headertextA </li> 
      <li> text1 </li> 
      <li> text2 </li> 
      <li> text3 </li> 
      <li class="parent"> headertextB </li> 
      <li> text4 </li> 
      <li> text5 </li> 
     </ul> 
     <div id="result"></div> 
    </body> 
</html> 
10

En fait, vous pouvez facilement le faire en utilisant nextUntil(). pas besoin d'écrire votre propre "nextUntil" car il existe déjà.

ex. -

$(".a").nextUntil(".b"); 

ou comme suggéré par Vincent -

$(".parent:first").nextUntil(".parent"); 
+0

Cela n'existait pas avant la version 1.4 de jQuery, qui a chuté un peu après l'heure de la question. Mais ouais, ça va marcher maintenant :) – Contra