2011-11-30 5 views
2

http://jsfiddle.net/JamesKyle/y7hBQ/Comment ajouter des classes nième élément avec jQuery

je fais une fonction de comptage simple jquery qui ajoute les classes suivantes:

  1. Première & Dernière
  2. Même & Odd
  3. nième-item- # (compte dans l'ordre)
  4. nième point - # (décompté)

J'ai fait les deux premiers assez facilement, mais les deux secondes me donnent du mal depuis que je suis nouveau à jQuery/Javascript

Vous pouvez voir le jsFiddle ici: http://jsfiddle.net/JamesKyle/y7hBQ/

C'est le code que je suis actuellement en utilisant:

$(document).ready(function() { 
    $('.count, ul').each(function() { 

     var countChildren = $(this).children(); 

     $(countChildren).filter(':even').addClass('even'); 
     $(countChildren).filter(':odd').addClass('odd'); 
     $(countChildren).first().addClass('first'); 
     $(countChildren).last().addClass('last'); 

     var numberOfChildren = $(countChildren).size(); 

     // $(countChildren).addClass('nth-item-' + #); 
     //          ⬆ 
     //       Fill with the elements number 

     // $(countChildren).addClass('nth-item--' + #); 
     //           ⬆ 
     //     Fill with the elements number (negative count) 
    }); 
}); 

Je ne se concentrant sur les lignes commentées

Encore une fois est ici le jsFiddle: http://jsfiddle.net/JamesKyle/y7hBQ/

Merci à l'avance!

MISE À JOUR:

J'ai deux solutions ci-dessous, je prévois de l'utiliser sur une très grande échelle, donc si vous pouvez recommander ce serait la façon la plus efficace, il me aiderait beaucoup! Merci!!

+0

Pour vos questions d'efficacité, vérifiez ma réponse. Vous devez vous rapprocher de javascript natif pour la solution la plus efficace. –

Répondre

1

Si chaque effiency compte alors vous devriez envisager de réduire les itérations;

$('.count, ul').each(function() { 
    var $children = $(this).children(), 
     count = $children.size(), 
     $item; 
    $children.each(function(i) { 
     $item = $(this) 
      .addClass(i % 2 === 0 ? 'even' : 'odd') 
      .addClass('nth-item-' + (i + 1)) 
      .addClass('nth-item--' + (count - i)); 
     if (i === 0) { 
      $item.addClass('first'); 
     } 
     if (i == count - 1) { 
      $item.addClass('last'); 
     } 
    }); 
}); 

De cette façon, vous ne réitérerez les enfants qu'une seule fois. Lorsque vous utilisez des filtres, il itère et filtre les éléments en fonction de votre filtre. jsFiddle here. Une petite référence est here.

+0

Excellent travail, je dois apprendre à faire ce que vous avez fait de référence –

+0

Btw, je ne voulais pas qu'ils soient un 0 sur le n-item compte, je vais mettre à jour votre réponse –

+0

J'ai raté cela. Mise à jour ma réponse –

3

Edit: Voir this fiddle pour une solution pure CSS. Il ne nécessite pas de JavaScript (en utilisant le sélecteur :nth-child).


utiliser la méthode .index() pour obtenir l'indice de l'élément courant à une collection d'éléments. En outre, puisque .children() renvoie un objet jQuery, il est inutile d'envelopper countChildren dans un $. Pour plus d'informations, le code ci-dessous utilise des index commençant à 1 et -1 (comme indiqué dans votre code CSS).

Démo: http://jsfiddle.net/y7hBQ/18/

$(document).ready(function() { 
    $('.count, ul').each(function() { 

     var countChildren = $(this).children(); 

     countChildren.filter(':even').addClass('even'); 
     countChildren.filter(':odd').addClass('odd'); 
     countChildren.first().addClass('first'); 
     countChildren.last().addClass('last'); 

     var numberOfChildren = countChildren.size(); 

     countChildren.each(function(i){ 
      var posindex = countChildren.index(this) + 1, 
         //^ This can be replaced by i + 1, for efficiency 
       negindex = numberOfChildren - posindex + 1; 
      $(this).addClass('nth-item-' + posindex) 
        .addClass('nth-item--' + negindex); 
     }); 

    }); 
}); 
+0

Pourrais-je me débarrasser de la variable 'numberOfChildren' en remplaçant l'instance par' countChildren.size() '? –

+1

C'est inefficace. Puisque '.size()' renvoie toujours la même valeur à ce point, il est préférable de mettre en cache la valeur. Imaginez que votre arbre a une taille de 2000 éléments. Cela entraînerait 2000 appels de fonction supplémentaires. –

+0

Oh d'accord, ignore mes modifications alors, merci! –

1

Si je comprends bien, ceci:

$(document).ready(function() { 
    $('.count, ul').each(function() { 

     var countChildren = $(this).children(); 

     countChildren.filter(':even').addClass('even'); 
     countChildren.filter(':odd').addClass('odd'); 
     countChildren.first().addClass('first'); 
     countChildren.last().addClass('last'); 

     var numberOfChildren = countChildren.size(); 

     countChildren.each(function(i) { 
      $(this).addClass('nth-item-' + (i + 1)) 
        .addClass('nth-item--' + (numberOfChildren - i)); 
     }); 
    }); 
}); 

jsFiddle

+0

Est-ce plus efficace que la réponse de @Rob W ci-dessus? –

+1

Le mien et le sien sont pratiquement les mêmes, étant donné son commentaire de '//^Ceci peut être remplacé par i + 1, pour l'efficacité'. L'appel à 'jQuery.index()' coûterait un peu, mais est trivial. – simshaun

+0

Eh bien, je prévois d'utiliser sur une très grande échelle de sorte que chaque efficacité compte –

1

Je pense que ce que vous recherchez est:

var count = countChildren.length; 
countChildren.each(function(index) { 
    $(this).addClass('nth-item-'+index); 
      .addClass('nth-item--'+(count-1-index)); 
}); 

Il peut y avoir un moyen plus rapide de le faire, mais .... j'espère que cela fonctionne pour vous.

Questions connexes