> ## Documentation Index
> Fetch the complete documentation index at: https://dokumentation.websale.de/llms.txt
> Use this file to discover all available pages before exploring further.

# Blättern in Produktlisten ohne Seitenwechsel

> Weitere Produkte einer Kategorie oder eines Suchergebnisses auf derselben Seite nachladen, wahlweise automatisch beim Scrollen oder über eine Schaltfläche.

Bei einer langen Kategorie oder einem großen Suchergebnis springt der Käufer von Seite zu Seite und verliert dabei seine Position. Stattdessen lassen sich die weiteren Produkte auf derselben Seite nachladen. Der Käufer scrollt dann nur noch auf und ab.

Zwei Auslöser sind gebräuchlich:

| Variante | Was den Nachschub auslöst |
| - | - |
| Infinity Scrolling | die nächsten Produkte laden von selbst, sobald der Käufer das Ende der Liste erreicht |
| Blättern mit Ajax | der Käufer klickt auf eine Schaltfläche, beispielsweise "Weitere Artikel laden" |

![Weitereartikelladen](https://mintcdn.com/websaleag-44ee7ea6/F0j7j4nmuETNasFh/images/weitereartikelladen.jpg?fit=max\&auto=format\&n=F0j7j4nmuETNasFh\&q=85\&s=711c03d0e7dff5feb022aaa401b4472e)

Der Template-Teil ist für beide Varianten derselbe. Nur das JavaScript unterscheidet sich.

Wegweiser: [Produktlisten blättern und Produkte je Seite](https://dokumentation.websale.de/v8s/funktionen-fuer-produktdaten/produktlisten-blaettern-und-produkte-je-seite.md)

## Das Template

```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{CAT-Data}
   <div class="wsAjaxLoad">
      {@PR-Data}
         <!-- Produktbox einfügen -->
      {/@PR-Data}

      {WS-ListPagingNext}
         <div class="wsCategoryPagingNextAjaxDelete">
            <a href="~WS-ListPagingNextLink~"
               class="wsCategoryPagingNext"
               data-ws-ajax-target=".wsAjaxTargetNext-~CAT-CurrPage~">Weitere Produkte laden</a>
         </div>
         <div class="wsAjaxTargetNext-~CAT-CurrPage~"></div>
      {/WS-ListPagingNext}
   </div>
{/CAT-Data}
```

### Wie die Teile zusammenspielen

| Element | Aufgabe |
| - | - |
| `.wsAjaxLoad` | umschließt alles, was nachgeladen werden soll. Das JavaScript holt sich aus der nächsten Seite genau diesen Ausschnitt |
| `{WS-ListPagingNext}` | greift nur, solange es eine nächste Seite gibt. Auf der letzten Seite verschwinden Schaltfläche und Zielbereich von selbst |
| `~WS-ListPagingNextLink~` | die echte Adresse der nächsten Seite |
| `.wsCategoryPagingNextAjaxDelete` | der Wrapper um die Schaltfläche. Nach dem Laden wird er entfernt, damit nicht zweimal dieselbe Seite geholt wird |
| `data-ws-ajax-target` | sagt dem Skript, wohin der nachgeladene Ausschnitt gehört |
| `~CAT-CurrPage~` | macht den Namen des Zielbereichs je Seite eindeutig |

> [!NOTE]
>
> Die Schaltfläche ist ein echter Link auf die nächste Seite. Das ist kein Schönheitsfehler, sondern der Grund, warum die Lösung tragfähig ist: Ohne JavaScript und für Suchmaschinen funktioniert die Liste weiter wie zuvor, mit ganz normalen Seiten.
>
> Ersetzen Sie den Link deshalb nicht durch ein `button`-Element.

> [!WARNING]
>
> Der ganze Block gehört in `{CAT-Data}`. Ohne diese Klammerung stehen die Produktdaten nicht zur Verfügung, und die Schleife `{@PR-Data}` bleibt leer.

Referenz: [CAT-Data](https://dokumentation.websale.de/v8s/referenz/tags/cat/navigation-und-kategoriebaum.md#cat-data) · [CAT-CurrPage](https://dokumentation.websale.de/v8s/referenz/tags/cat/sortieren-und-blaettern.md#die-tags-im-uberblick) · [WS-ListPagingNext](https://dokumentation.websale.de/v8s/referenz/tags/ws/suche-listen-und-blaettern.md#eigene-vor-und-zuruck-schaltflachen) · [WS-ListPagingNextLink](https://dokumentation.websale.de/v8s/referenz/tags/ws/suche-listen-und-blaettern.md#eigene-vor-und-zuruck-schaltflachen)

## Voraussetzung: jQuery

Beide Skripte laden den Ausschnitt mit `$(…).load(…)`, einer Funktion von jQuery. Ohne eingebundenes jQuery passiert nichts, und in der Konsole des Browsers steht `$ is not defined`.

> [!WARNING]
>
> Prüfen Sie, ob Ihr Template jQuery überhaupt einbindet, bevor Sie eine der beiden Varianten übernehmen. Die Schaltfläche funktioniert dann zwar weiterhin, sie führt aber zu einem gewöhnlichen Seitenwechsel statt zum Nachladen. Der Fehler fällt deshalb leicht durch.
>
> `load()` entfernt aus dem geholten Ausschnitt alle `script`-Elemente, sobald wie hier ein Selektor angegeben ist. Enthalten Ihre Produktboxen eigene Skripte, beispielsweise für eine Variantenauswahl oder für Tracking, laufen diese in den nachgeladenen Produkten nicht.
>
> Prüfen Sie eine nachgeladene Produktbox deshalb genauso gründlich wie eine aus dem ersten Durchgang.

## Variante 1: Infinity Scrolling

```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
<script>
   function isInViewport(el) {
      var rect = el.getBoundingClientRect();
      return rect.top >= 0 && rect.top < (window.innerHeight || document.documentElement.clientHeight);
   }

   document.addEventListener('scroll', function () {
      var wsCategoryPagingNext = document.querySelector('.wsCategoryPagingNext');
      if (wsCategoryPagingNext) {
         if (isInViewport(wsCategoryPagingNext)) {
            var wsAjaxTarget = wsCategoryPagingNext.getAttribute("data-ws-ajax-target");
            var wsAjaxTargetLink = wsCategoryPagingNext.getAttribute("href");
            var wsAjaxTargetElement = document.querySelector(wsAjaxTarget);
            $(wsAjaxTargetElement).load(wsAjaxTargetLink + " .wsAjaxLoad");
            document.querySelector(".wsCategoryPagingNextAjaxDelete").remove();
         }
      }
   }, {
      passive: true
   });
</script>
```

Das Skript entfernt den Wrapper unmittelbar nach dem Auslösen und nicht erst, wenn die Antwort da ist. Das ist Absicht. Ein Scroll-Ereignis feuert mehrmals pro Sekunde, und ohne diese Sperre würde dieselbe Seite mehrfach angefordert.

`passive: true` sagt dem Browser zu, dass das Scrollen nicht unterbunden wird. Er muss dann nicht auf das Skript warten, und das Scrollen bleibt flüssig.

> [!WARNING]
>
> Infinity Scrolling schiebt die Fußzeile mit jedem Nachladen weiter nach unten. Alles, was dort steht, wird praktisch unerreichbar. Wenn Ihre Fußzeile Pflichtangaben oder viel genutzte Verweise enthält, ist die Variante mit der Schaltfläche die bessere Wahl.

## Variante 2: Blättern mit Ajax

```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
<script>
   document.body.addEventListener("click", function(e) {
      var wsPagingButton = e.target;
      while (wsPagingButton) {
         if (wsPagingButton.classList.contains("wsCategoryPagingNext")) {
            e.preventDefault();
            var wsAjaxTarget = wsPagingButton.getAttribute("data-ws-ajax-target");
            var wsAjaxTargetLink = wsPagingButton.getAttribute("href");
            var wsAjaxTargetElement = document.querySelector(wsAjaxTarget);
            $(wsAjaxTargetElement).load(wsAjaxTargetLink + " .wsAjaxLoad");
            document.querySelector(".wsCategoryPagingNextAjaxDelete").remove();
            break;
         } else {
            wsPagingButton = wsPagingButton.parentNode;
            if (wsPagingButton == document) {
               break;
            }
         }
      }
   });
</script>
```

> [!NOTE]
>
> Der Zuhörer hängt an `document.body` und nicht an der Schaltfläche selbst. Das ist nötig, weil jede nachgeladene Seite eine neue Schaltfläche mitbringt, die es beim Laden der Seite noch gar nicht gab.
>
> Die `while`-Schleife läuft vom angeklickten Element nach oben, bis sie die Klasse findet. So funktioniert der Klick auch dann, wenn in der Schaltfläche noch ein Symbol oder ein `span` steckt.

## Worauf Sie achten sollten

> [!WARNING]
>
> Beide Skripte entfernen die Schaltfläche, sobald sie den Ladevorgang angestoßen haben, und prüfen nicht, ob er gelingt. Antwortet der Server nicht, bleibt die Liste ohne jeden Hinweis stehen, und der Käufer hat keine Möglichkeit mehr, weiterzublättern.
>
> Ergänzen Sie deshalb eine Rückmeldung für den Ladevorgang und einen Weg zurück, wenn er fehlschlägt. `load()` nimmt dafür eine Funktion als zweites Argument entgegen, die nach dem Ende des Vorgangs läuft.

Der nachgeladene Ausschnitt bringt seinen eigenen `.wsAjaxLoad`-Bereich mit und landet innerhalb des vorigen. Die Produktliste wird also mit jedem Nachladen eine Ebene tiefer verschachtelt. Für das Blättern spielt das keine Rolle, für CSS-Regeln, die auf eine feste Verschachtelungstiefe setzen, schon.

Die Adresse in der Adresszeile ändert sich beim Nachladen nicht. Verlässt der Käufer die Seite und kommt über die Zurück-Schaltfläche seines Browsers wieder, steht er am Anfang der Liste. Dasselbe gilt, wenn er jemandem den Link schickt.

Nachgeladene Produkte erscheinen ohne Ankündigung. Wer die Seite mit der Tastatur bedient, verliert beim Entfernen der Schaltfläche den Punkt, an dem er gerade war. Setzen Sie den Fokus deshalb nach dem Laden auf den Anfang des neuen Abschnitts und kennzeichnen Sie den Zielbereich mit `aria-live`.

Die Seiten bleiben als eigene Adressen bestehen, auch wenn der Käufer sie nicht mehr aufruft. Die Vorkehrungen gegen doppelte Inhalte in Suchmaschinen gelten deshalb unverändert weiter.

## Verwandte Themen

* Wegweiser: [Produktlisten blättern und Produkte je Seite](https://dokumentation.websale.de/v8s/funktionen-fuer-produktdaten/produktlisten-blaettern-und-produkte-je-seite.md)
* Wegweiser: [Produkte einer Kategorie](https://dokumentation.websale.de/v8s/kategorien/produkte-einer-kategorie.md)
* Wegweiser: Blättern in Suchergebnissen
* Referenz: [CAT- (Kategorien)](https://dokumentation.websale.de/v8s/referenz/tags/cat/kategoriedaten.md)


## Related topics

- [Anwendungsbeispiele](https://dokumentation.websale.de/v8s/anwendungsbeispiele/anwendungsbeispiele.md)
- [Produktlisten sortieren und blättern](https://dokumentation.websale.de/v8s/referenz/tags/cat/sortieren-und-blaettern.md)
- [Produktlisten blättern und Produkte je Seite](https://dokumentation.websale.de/v8s/funktionen-fuer-produktdaten/produktlisten-blaettern-und-produkte-je-seite.md)
- [Produktlisten sortieren](https://dokumentation.websale.de/v8s/funktionen-fuer-produktlisten/produktlisten-sortieren.md)
- [Suche, Listen und Blättern](https://dokumentation.websale.de/v8s/referenz/tags/ws/suche-listen-und-blaettern.md)


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.