jQuery / Sélecteur / :odd - Sélectionner les indices impairs

Le sélecteur jQuery :odd retient les indices 1, 3, 5, etc., dans l'ensemble sélectionné, en comptant à partir de zéro. Il s'agit donc des deuxième, quatrième et sixième éléments. Attendre la première ligne à cause du mot « impair » inverse le résultat attendu. Dans du nouveau code, délimitez la sélection avec un sélecteur CSS ordinaire, puis utilisez .odd().

Comprendre :odd et passer à .odd()

La documentation de :odd indique une dépréciation depuis jQuery 3.4 et recommande la méthode .odd(). Ajoutée en 3.5, elle ne prend aucun argument et crée un nouvel objet jQuery contenant les éléments d'indices impairs de l'ensemble courant. Dépréciation et suppression diffèrent : la comparaison a été exécutée avec succès en 3.7.1 et 4.0.0.

Remplacez $("#records > tbody > tr:odd") par $("#records > tbody > tr").odd(). Cette méthode n'existe pas avant 3.5 ; vérifiez la compatibilité de l'application et des extensions avant une mise à niveau.

Expression Base du comptage Résultat initial
:odd ou .odd() sur les tr du tbody Ensemble des lignes de données, depuis zéro r2, r4
.odd() sur tous les tr avec l'en-tête L'en-tête occupe l'indice zéro r1, r3, r5
tbody tr:nth-child(odd) Position parmi les frères de chaque parent, depuis un r1, r3, r5

Exécuter un exemple complet de tableau

Enregistrez tout le code en UTF-8 dans odd-demo.html et ouvrez-le dans un navigateur. Aucun paquet n'est à installer. Il faut une connexion internet pour charger la distribution officielle par son réseau de diffusion de contenu, ou CDN. L'exemple utilise 4.0.0.

thead contient une ligne d'en-tête et tbody cinq lignes de données. Les identifiants servent à reconnaître les lignes ; les indices dépendent de l'ordre actuel du document et du périmètre de sélection. Les boutons changent ces conditions.

<!doctype html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title>Odd indexes in table rows</title>
  <style>
    body { font: 16px/1.6 sans-serif; margin: 24px; }
    table { border-collapse: collapse; width: 100%; max-width: 600px; }
    th, td { border: 1px solid #ccc; padding: 8px; text-align: left; }
    tr.marked { background: #fff0b3; }
    button { margin: 4px; padding: 8px; }
  </style>
  <script src="https://code.jquery.com/jquery-4.0.0.min.js"></script>
</head>
<body>
  <h1>Odd indexes in table rows</h1>
  <table id="records">
    <thead><tr id="heading"><th>Item</th><th>Amount</th></tr></thead>
    <tbody>
      <tr id="r1" class="eligible"><td>Item 1</td><td>10</td></tr>
      <tr id="r2"><td>Item 2</td><td>20</td></tr>
      <tr id="r3" class="eligible"><td>Item 3</td><td>30</td></tr>
      <tr id="r4" class="eligible"><td>Item 4</td><td>40</td></tr>
      <tr id="r5" class="eligible"><td>Item 5</td><td>50</td></tr>
    </tbody>
  </table>
  <button type="button" id="data">Data rows .odd()</button>
  <button type="button" id="all">Include header .odd()</button>
  <button type="button" id="css">Data :nth-child(odd)</button>
  <button type="button" id="prepend">Prepend one data row</button>
  <button type="button" id="reset">Reset</button>
  <p id="result" aria-live="polite"></p>
  <script>
    $(function () {
      function show($chosen) {
        $("#records tr").removeClass("marked");
        $chosen.addClass("marked");
        const ids = $chosen.map((_, row) => row.id).get().join(", ");
        $("#result").text(`${ids || "none"} | ${$chosen.length}`);
      }
      function dataRows() {
        show($("#records > tbody > tr").odd());
      }
      $("#data").on("click", dataRows);
      $("#all").on("click", () => show($("#records tr").odd()));
      $("#css").on("click", () => show($("#records > tbody > tr:nth-child(odd)")));
      $("#prepend").on("click", function () {
        if (!$("#extra").length) {
          $("#records > tbody").prepend('<tr id="extra"><td>Extra item</td><td>0</td></tr>');
        }
        dataRows();
      });
      $("#reset").on("click", function () {
        $("#extra").remove();
        dataRows();
      });
      dataRows();
    });
  </script>
</body>
</html>

Au départ, .odd() s'applique seulement aux données. Item 2 et Item 4 sont surlignés, avec ce résultat :

r2, r4 | 2

Changer le périmètre, insérer puis réinitialiser

  1. Data rows .odd() ne compte que les tr enfants directs de tbody. Les indices 1 et 3 donnent r2, r4 | 2.
  2. Include header .odd() inclut la ligne de thead. L'en-tête prend l'indice zéro : r1, r3, r5 | 3.
  3. Data :nth-child(odd) choisit les positions 1, 3 et 5 dans tbody : r1, r3, r5 | 3. Un résultat identique à celui du bouton précédent ne signifie pas une règle identique.
  4. Prepend one data row insère Extra item au début de tbody et recalcule .odd(). L'ancien r1 passe à l'indice 1 : r1, r3, r5 | 3. La vérification de l'identifiant extra évite les doublons lors de clics répétés.
  5. Reset enlève uniquement la ligne ajoutée et réapplique .odd() aux données. Les cinq lignes et valeurs d'origine restent présentes ; r2, r4 | 2 est rétabli.

show retire toutes les classes marked précédentes avant de marquer le nouveau résultat. Les surlignages ne s'accumulent donc pas. Dans un tableau réel, limitez également l'identifiant et les relations d'enfants directs pour exclure les tableaux étrangers ou imbriqués.

Comparer avec odd en CSS

Juste après l'ouverture ou Reset, exécutez ce fragment dans la console des outils de développement. Les deux premières lignes comparent l'ancien sélecteur et son remplacement ; la dernière utilise :nth-child() selon les règles CSS.

const ids = $set => $set.map((_, row) => row.id).get().join(", ");
console.log(ids($("#records > tbody > tr:odd")));
console.log(ids($("#records > tbody > tr").odd()));
console.log(ids($("#records > tbody > tr:nth-child(odd)")));
r2, r4
r2, r4
r1, r3, r5

.odd() compte l'ensemble sélectionné en une seule suite. :nth-child(odd) recommence pour chaque parent, notamment pour plusieurs tbody. :nth-child() compte tous les éléments frères, quelle que soit leur balise, puis exige que le candidat à cette position corresponde aussi à tr. Les espaces textuels et les commentaires ne sont pas des éléments frères.

Ordre des filtres et lignes dynamiques

r1, r3, r4 et r5 possèdent eligible. $("#records > tbody > tr.eligible").odd() rassemble d'abord ces quatre lignes et garde r3 et r5. Appliquer .odd() aux cinq lignes avant .filter(".eligible") ne garde que r4 parmi r2 et r4. L'ordre change l'ensemble servant au calcul des indices.

Un ensemble vide ou réduit à un élément n'a pas d'indice 1 : .odd() renvoie donc un ensemble vide. Les résultats ne s'actualisent pas automatiquement. Une sélection de r2 et r4 enregistrée avant l'insertion contient toujours ces éléments après celle-ci. Refaites la requête, comme dataRows, pour refléter les positions actuelles.

En cas d'absence de réaction, vérifiez la requête jQuery dans Network, les erreurs dans Console et jQuery.fn.jquery. Si le résultat semble inversé, contrôlez l'en-tête, le tbody ciblé, l'ordre des filtres et les lignes ajoutées. Distinguez numéro visible et indice commençant à zéro.