jQuery / Methode / .slice() - Einen Indexbereich auswählen

jQuerys .slice(start, end) liefert ein neues jQuery-Objekt für einen Bereich der aktuellen Menge: start wird eingeschlossen, end ausgeschlossen. Indizes beginnen bei null; ohne end geht der Bereich bis zum letzten Element. Andere Elemente werden weder aus der ursprünglichen Menge noch aus dem Dokument gelöscht.

Bereiche und negative Indizes lesen

Indizes der .slice()-API beziehen sich auf die aktuelle Menge, nicht auf Geschwisterpositionen unter einem HTML-Elternteil. Alpha, Beta, Gamma, Delta, Epsilon und Zeta haben 0 bis 5. Negative Werte zählen vom Ende; -1 bezeichnet die letzte Position.

Aufruf Ergebnis bei sechs Elementen Grund
.slice(1, 4) Beta, Gamma, Delta 1 eingeschlossen, 4 ausgeschlossen
.slice(2) Gamma bis Zeta Ende ausgelassen
.slice(-2) Epsilon, Zeta Vorletztes bis Ende
.slice(1, -1) Beta bis Epsilon Vor letzter Position stoppen
.slice(3, 3), .slice(4, 2) Leere Menge Kein vorwärts gerichteter Bereich

end ist keine Anzahl: .slice(1, 4) wählt drei Elemente an 1, 2 und 3. Für ein einzelnes Element eignet sich .eq(index). .filter() prüft Bedingungen statt eines zusammenhängenden Bereichs.

Vollständiges Beispiel mit Filterreihenfolge

Speichern Sie alles in UTF-8 als slice-demo.html und öffnen Sie die Datei im Browser. Die offizielle jQuery-Datei 4.0.0 vom Content Delivery Network (CDN) benötigt Internet, keine Installation. Bereiche, Filterreihenfolge, Ergänzen, Reset und Konsolencode wurden mit 3.7.1 und 4.0.0 ausgeführt.

eligible kennzeichnet passende Beispieleinträge. Anfangs existieren sechs Elemente; nur der ausgewählte Bereich wird türkis markiert. Alle anderen bleiben im Dokument.

<!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>

Anfangs wählt .slice(1, 4) drei Elemente. source und DOM items bleiben sechs.

source=6
selected=3: Beta, Gamma, Delta
DOM items=6
  1. slice(-2) markiert Epsilon und Zeta; slice(1, -1) Beta, Gamma, Delta und Epsilon. Vergleichen Sie jeweils eine Änderung nach Reset.
  2. filter('.eligible').slice(1, 3) reduziert zuerst auf Alpha, Gamma, Epsilon und Zeta. Deren Positionen 1 und 2 sind Gamma und Epsilon.
  3. slice(1, 3).filter('.eligible') wählt zuerst Beta und Gamma, dann nur Gamma. Die vorherige Menge bestimmt die Indexbedeutung.
  4. slice(4, 2) ergibt null Treffer ohne Löschen der sechs ursprünglichen Einträge.
  5. Bei slice(-2) ergänzt Add Eta den Eintrag: Zeta und Eta sind ausgewählt, weil report() alle sieben neu wählt. Mehrfache Ergänzungen werden verhindert.
  6. Reset stellt Liste und .slice(1, 4)-Modus wieder her.

Ein gespeichertes const $last = $("#items > li").slice(-2) folgt neuen Ergänzungen nicht automatisch. Es behält Epsilon und Zeta. Wählen Sie nach Änderungen des Document Object Model (DOM) erneut, wenn der aktuelle Bereich benötigt wird.

Grenzen prüfen und Seitenbereiche berechnen

Führen Sie nach Reset Folgendes in der Entwicklerkonsole aus. Überlange Grenzen werden auf die verfügbare Länge begrenzt; ein Start hinter dem Ende ergibt leer. Die letzte Zeile zeigt gleiche DOM-Referenzen statt Kopien trotz neuer jQuery-Menge.

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

Bei Seitennummern ab eins und positiver ganzzahliger Seitengröße ist start=(page - 1) × pageSize und end=start + pageSize. Der folgende Konsolencode wählt zwei Einträge der zweiten Seite. Prüfen Sie Werte vorher, damit negative Seiten nicht als rückwärtige slice-Indizes gelten.

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

Dies berechnet einen Ausschnitt, ohne andere Einträge zu verstecken oder Serverdaten abzurufen. Echte Seitennavigation braucht getrennte Anzeige-, Gesamtzahl- und Seitenverwaltung. Bereits geladene Elemente auszuwählen reduziert nicht von selbst Serverarbeit oder Downloadmenge.

Unerwartete Elemente untersuchen

Prüfen Sie zuerst .length und Mengenreihenfolge. Engere Selektoren und vorheriges .filter() verändern den Bezug. Verwechseln Sie ihn nicht mit CSS-Geschwisterpositionen oder Nummerierung ab eins. Für einen eingeschlossenen letzten Wunschindex übergeben Sie diesen plus eins als end.

slice selbst klont, verschiebt und löscht nicht. .addClass() oder .text() auf dem Ergebnis verändert dennoch die gemeinsam referenzierten echten Knoten. Für unabhängige Knoten ist bewusstes Klonen nötig. Auch ein leeres jQuery-Objekt ist wahrwertig; prüfen Sie .length statt seines booleschen Werts.