jQuery / Méthode / .slice() - Sélectionner une plage d’indices

Dans jQuery, .slice(start, end) renvoie un nouvel objet jQuery pour une plage de la collection actuelle, avec start inclus et end exclu. Les indices commencent à zéro ; omettre end sélectionne jusqu’au dernier élément. Les autres éléments ne sont supprimés ni de la collection initiale ni du document.

Lire les plages et les indices négatifs

Les indices de l’API .slice() désignent la collection actuelle, pas les positions des frères dans un parent HTML. Alpha, Beta, Gamma, Delta, Epsilon et Zeta occupent 0 à 5. Les valeurs négatives comptent depuis la fin ; -1 désigne la dernière position.

Appel Résultat parmi six éléments Raison
.slice(1, 4) Beta, Gamma, Delta 1 inclus, 4 exclu
.slice(2) Gamma à Zeta Fin omise
.slice(-2) Epsilon, Zeta Avant-dernier jusqu’à la fin
.slice(1, -1) Beta à Epsilon Arrêt avant la dernière position
.slice(3, 3), .slice(4, 2) Collection vide Aucun intervalle vers l’avant

end n’est pas un nombre d’éléments : .slice(1, 4) choisit trois positions, 1, 2 et 3. Utilisez .eq(index) pour un seul élément. .filter() sélectionne selon des conditions plutôt qu’une plage continue.

Exemple complet des plages et de l’ordre des filtres

Enregistrez tout le code en UTF-8 dans slice-demo.html et ouvrez-le dans le navigateur. Internet est nécessaire pour le fichier jQuery officiel 4.0.0 du réseau de diffusion de contenu (CDN), sans installation. Les plages, filtres, ajouts, réinitialisations et extraits de console ont été exécutés avec 3.7.1 et 4.0.0.

eligible est une classe d’exemple marquant les éléments admissibles. Les six éléments initiaux restent dans le document ; seule la sélection est surlignée en turquoise.

<!doctype html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title>Select a range from a collection</title>
  <script src="https://code.jquery.com/jquery-4.0.0.min.js"></script>
  <style>
    body { font: 16px/1.6 sans-serif; max-width: 760px; margin: 24px auto; padding: 16px; }
    button, select { font: inherit; margin: 4px; max-width: 100%; }
    li { border: 1px solid #aab; padding: 8px; margin: 4px; }
    .picked { background: #d9f4ef; border-color: teal; }
    pre { white-space: pre-wrap; overflow-wrap: anywhere; }
  </style>
</head>
<body>
  <h1>Select a collection range</h1>
  <label for="mode">Range:</label>
  <select id="mode">
    <option value="middle">slice(1, 4)</option>
    <option value="last">slice(-2)</option>
    <option value="inner">slice(1, -1)</option>
    <option value="from">slice(2)</option>
    <option value="filterFirst">filter('.eligible').slice(1, 3)</option>
    <option value="sliceFirst">slice(1, 3).filter('.eligible')</option>
    <option value="empty">slice(4, 2)</option>
  </select>
  <button type="button" id="add">Add Eta</button>
  <button type="button" id="reset">Reset</button>
  <ul id="items">
    <li class="eligible" data-name="Alpha">Alpha (eligible)</li>
    <li data-name="Beta">Beta</li>
    <li class="eligible" data-name="Gamma">Gamma (eligible)</li>
    <li data-name="Delta">Delta</li>
    <li class="eligible" data-name="Epsilon">Epsilon (eligible)</li>
    <li class="eligible" data-name="Zeta">Zeta (eligible)</li>
  </ul>
  <pre id="result" aria-live="polite"></pre>
  <script>
    $(function () {
      const initial = $("#items").html();
      function report() {
        const $all = $("#items > li");
        let $selected;
        switch ($("#mode").val()) {
          case "last": $selected = $all.slice(-2); break;
          case "inner": $selected = $all.slice(1, -1); break;
          case "from": $selected = $all.slice(2); break;
          case "filterFirst": $selected = $all.filter(".eligible").slice(1, 3); break;
          case "sliceFirst": $selected = $all.slice(1, 3).filter(".eligible"); break;
          case "empty": $selected = $all.slice(4, 2); break;
          default: $selected = $all.slice(1, 4);
        }
        $all.removeClass("picked");
        $selected.addClass("picked");
        const names = $selected.map(function () { return this.dataset.name; }).get();
        $("#result").text(`source=${$all.length}\nselected=${$selected.length}: ${names.join(", ") || "(none)"}\nDOM items=${$("#items > li").length}`);
      }
      $("#mode").on("change", report);
      $("#add").on("click", function () {
        if (!$("#eta").length) $("#items").append('<li id="eta" class="eligible" data-name="Eta">Eta (eligible)</li>');
        report();
      });
      $("#reset").on("click", function () { $("#items").html(initial); $("#mode").val("middle"); report(); });
      report();
    });
  </script>
</body>
</html>

Au départ, .slice(1, 4) sélectionne trois éléments. source et DOM items restent à six.

source=6
selected=3: Beta, Gamma, Delta
DOM items=6
  1. slice(-2) surligne Epsilon et Zeta ; slice(1, -1) Beta, Gamma, Delta et Epsilon. Réinitialisez et changez une condition à la fois.
  2. filter('.eligible').slice(1, 3) réduit d’abord à Alpha, Gamma, Epsilon et Zeta, puis choisit les positions 1 et 2 : Gamma et Epsilon.
  3. slice(1, 3).filter('.eligible') choisit d’abord Beta et Gamma, puis garde Gamma. La collection précédente change la référence des indices.
  4. slice(4, 2) renvoie zéro élément sans supprimer les six initiaux.
  5. Avec slice(-2), appuyez sur Add Eta : Zeta et Eta deviennent sélectionnés, car report() resélectionne les sept éléments. Les ajouts en double sont empêchés.
  6. Reset restaure la liste et le mode .slice(1, 4).

Une sélection conservée dans const $last = $("#items > li").slice(-2) ne suit pas automatiquement les ajouts. Elle garde Epsilon et Zeta. Resélectionnez après les changements du modèle objet du document (DOM) si vous voulez la plage actuelle.

Vérifier les limites et calculer une portion de page

Après Reset, exécutez ceci dans la console des outils de développement. Les limites excessives sont ramenées à la longueur disponible ; un début au-delà de la fin donne une collection vide. La dernière ligne confirme que les nœuds sont les mêmes références, pas des copies.

const $items = $("#items > li");
const names = $set => $set.map(function () { return this.dataset.name; }).get().join(",");
console.log(`slice(1,4)=${names($items.slice(1, 4))}`);
console.log(`slice(-2)=${names($items.slice(-2))}`);
console.log(`slice(1,-1)=${names($items.slice(1, -1))}`);
console.log(`equal bounds=${$items.slice(3, 3).length}; beyond end=${$items.slice(10).length}`);
console.log(`clamped range=${$items.slice(-99, 99).length}; original=${$items.length}`);
console.log(`same node=${$items.slice(1, 2).get(0) === $items.get(1)}`);
slice(1,4)=Beta,Gamma,Delta
slice(-2)=Epsilon,Zeta
slice(1,-1)=Beta,Gamma,Delta,Epsilon
equal bounds=0; beyond end=0
clamped range=6; original=6
same node=true

Avec des pages numérotées dès un et une taille entière positive, start=(page - 1) × pageSize et end=start + pageSize. Cet extrait sélectionne deux éléments pour la page deux. Vérifiez les valeurs : une page négative pourrait sinon devenir un indice depuis la fin.

const page = 2;
const pageSize = 2;
if (!Number.isInteger(page) || page < 1 || !Number.isInteger(pageSize) || pageSize < 1) {
  throw new RangeError("Use positive integer page and pageSize");
}
const start = (page - 1) * pageSize;
const $pageItems = $("#items > li").slice(start, start + pageSize);
console.log(`page=${page}: ${$pageItems.map(function () { return this.dataset.name; }).get().join(",")}`);
page=2: Gamma,Delta

Le code calcule une sélection, sans masquer les autres éléments ni demander des données au serveur. Une navigation réelle demande une gestion séparée de l’affichage, du total et de la page actuelle. Découper des éléments déjà chargés ne réduit pas à lui seul le travail serveur ou le volume téléchargé.

Comprendre une sélection inattendue

Vérifiez d’abord .length et l’ordre actuel. Un sélecteur plus étroit ou un .filter() préalable change la collection de référence. Ne confondez pas les indices avec la numérotation CSS des frères ou un comptage dès un. Pour inclure le dernier indice souhaité, passez cet indice plus un comme end.

slice ne copie, déplace ni supprime les nœuds. Mais .addClass() ou .text() sur le résultat modifie les vrais nœuds partagés. Utilisez un clonage explicite pour des nœuds indépendants. Même vide, un objet jQuery est vrai dans une condition : vérifiez .length plutôt que sa valeur booléenne.