Fix: Shop-Filter-Dropdowns (Kategorie/Mindestbewertung) reagierten nach Client-Router-Navigation nicht mehr

Beide <script>-Blöcke am Ende von shop/index.astro (+en/ch/fr) liefen bisher direkt beim Parsen,
statt wie in Layout.astro etabliert in "astro:page-load" gekapselt zu sein. Da <ClientRouter
fallback="swap" /> Inline-Skripte bei einem clientseitigen Seitenwechsel nicht erneut ausführt,
wurden die Klick-Listener der beiden eigenen Dropdowns nie angehängt, wenn man per Link (statt
Direktaufruf) auf /shop/ navigiert ist — Preis-Regler/Checkbox blieben unbemerkt funktionsfähig,
weil das natives Browser-Verhalten ohne JS ist.
This commit is contained in:
qcigano
2026-08-04 14:55:24 +02:00
parent f4329da1c1
commit 6fae5a0694
4 changed files with 60 additions and 0 deletions
+15
View File
@@ -119,6 +119,14 @@ const t = useTranslations(lang);
</Layout> </Layout>
<script define:vars={{ productSingular: t.shop.productSingular, productPlural: t.shop.productPlural, unitFirst: lang === "en" }}> <script define:vars={{ productSingular: t.shop.productSingular, productPlural: t.shop.productPlural, unitFirst: lang === "en" }}>
// WICHTIG: In Layout.astro läuft <ClientRouter fallback="swap" /> (Astro View Transitions) für
// die ganze Seite. Bei einem clientseitigen Seitenwechsel (Link-Klick statt Hard-Reload) werden
// Inline-<script>-Tags NICHT erneut ausgeführt — nur beim allerersten Laden. Deshalb (genau wie
// in Layout.astro) die komplette Initialisierung in "astro:page-load" kapseln, das zuverlässig
// sowohl beim ersten Laden als auch nach jedem ClientRouter-Seitenwechsel feuert. Sonst würden
// die Klick-Listener der beiden eigenen Dropdowns (Kategorie/Mindestbewertung) nie angehängt,
// wenn man per Link (statt Direktaufruf) auf /shop/ navigiert.
document.addEventListener("astro:page-load", () => {
const grid = document.getElementById("product-grid"); const grid = document.getElementById("product-grid");
const slots = Array.from(grid.querySelectorAll(".product-slot")); const slots = Array.from(grid.querySelectorAll(".product-slot"));
const kategorieSel = document.getElementById("f-kategorie"); const kategorieSel = document.getElementById("f-kategorie");
@@ -242,11 +250,17 @@ const t = useTranslations(lang);
// hier nutzt define:vars und darf deshalb selbst kein "import" enthalten (siehe unten). // hier nutzt define:vars und darf deshalb selbst kein "import" enthalten (siehe unten).
window.__shopApply = apply; window.__shopApply = apply;
apply(); apply();
});
</script> </script>
<script> <script>
import { lokaleBewertungenFuer } from "../../../scripts/reviews"; import { lokaleBewertungenFuer } from "../../../scripts/reviews";
// Siehe Kommentar im ersten Skript oben: wegen <ClientRouter fallback="swap" /> in Layout.astro
// muss auch dieses Modul-Skript bei jedem Seitenwechsel erneut laufen, nicht nur beim ersten
// Laden — deshalb ebenfalls in einen eigenen "astro:page-load"-Handler gekapselt. Der Import
// bleibt bewusst außerhalb des Listeners (Modul-Imports müssen top-level stehen).
document.addEventListener("astro:page-load", () => {
// Lokal auf diesem Gerät gespeicherte Kundenrezensionen (siehe scripts/reviews.ts) in // Lokal auf diesem Gerät gespeicherte Kundenrezensionen (siehe scripts/reviews.ts) in
// data-bewertung einrechnen und danach neu filtern/sortieren — sonst würden der // data-bewertung einrechnen und danach neu filtern/sortieren — sonst würden der
// Mindestbewertung-Filter und die Sortierung "Beste Bewertung" neue Rezensionen ignorieren. // Mindestbewertung-Filter und die Sortierung "Beste Bewertung" neue Rezensionen ignorieren.
@@ -262,4 +276,5 @@ const t = useTranslations(lang);
slot.dataset.bewertung = String(summe / (basisAnzahl + lokale.length)); slot.dataset.bewertung = String(summe / (basisAnzahl + lokale.length));
}); });
(window as any).__shopApply?.(); (window as any).__shopApply?.();
});
</script> </script>
+15
View File
@@ -119,6 +119,14 @@ const t = useTranslations(lang);
</Layout> </Layout>
<script define:vars={{ productSingular: t.shop.productSingular, productPlural: t.shop.productPlural, unitFirst: lang === "en" }}> <script define:vars={{ productSingular: t.shop.productSingular, productPlural: t.shop.productPlural, unitFirst: lang === "en" }}>
// WICHTIG: In Layout.astro läuft <ClientRouter fallback="swap" /> (Astro View Transitions) für
// die ganze Seite. Bei einem clientseitigen Seitenwechsel (Link-Klick statt Hard-Reload) werden
// Inline-<script>-Tags NICHT erneut ausgeführt — nur beim allerersten Laden. Deshalb (genau wie
// in Layout.astro) die komplette Initialisierung in "astro:page-load" kapseln, das zuverlässig
// sowohl beim ersten Laden als auch nach jedem ClientRouter-Seitenwechsel feuert. Sonst würden
// die Klick-Listener der beiden eigenen Dropdowns (Kategorie/Mindestbewertung) nie angehängt,
// wenn man per Link (statt Direktaufruf) auf /shop/ navigiert.
document.addEventListener("astro:page-load", () => {
const grid = document.getElementById("product-grid"); const grid = document.getElementById("product-grid");
const slots = Array.from(grid.querySelectorAll(".product-slot")); const slots = Array.from(grid.querySelectorAll(".product-slot"));
const kategorieSel = document.getElementById("f-kategorie"); const kategorieSel = document.getElementById("f-kategorie");
@@ -242,11 +250,17 @@ const t = useTranslations(lang);
// hier nutzt define:vars und darf deshalb selbst kein "import" enthalten (siehe unten). // hier nutzt define:vars und darf deshalb selbst kein "import" enthalten (siehe unten).
window.__shopApply = apply; window.__shopApply = apply;
apply(); apply();
});
</script> </script>
<script> <script>
import { lokaleBewertungenFuer } from "../../../scripts/reviews"; import { lokaleBewertungenFuer } from "../../../scripts/reviews";
// Siehe Kommentar im ersten Skript oben: wegen <ClientRouter fallback="swap" /> in Layout.astro
// muss auch dieses Modul-Skript bei jedem Seitenwechsel erneut laufen, nicht nur beim ersten
// Laden — deshalb ebenfalls in einen eigenen "astro:page-load"-Handler gekapselt. Der Import
// bleibt bewusst außerhalb des Listeners (Modul-Imports müssen top-level stehen).
document.addEventListener("astro:page-load", () => {
// Lokal auf diesem Gerät gespeicherte Kundenrezensionen (siehe scripts/reviews.ts) in // Lokal auf diesem Gerät gespeicherte Kundenrezensionen (siehe scripts/reviews.ts) in
// data-bewertung einrechnen und danach neu filtern/sortieren — sonst würden der // data-bewertung einrechnen und danach neu filtern/sortieren — sonst würden der
// Mindestbewertung-Filter und die Sortierung "Beste Bewertung" neue Rezensionen ignorieren. // Mindestbewertung-Filter und die Sortierung "Beste Bewertung" neue Rezensionen ignorieren.
@@ -262,4 +276,5 @@ const t = useTranslations(lang);
slot.dataset.bewertung = String(summe / (basisAnzahl + lokale.length)); slot.dataset.bewertung = String(summe / (basisAnzahl + lokale.length));
}); });
(window as any).__shopApply?.(); (window as any).__shopApply?.();
});
</script> </script>
+15
View File
@@ -119,6 +119,14 @@ const t = useTranslations(lang);
</Layout> </Layout>
<script define:vars={{ productSingular: t.shop.productSingular, productPlural: t.shop.productPlural, unitFirst: lang === "en" }}> <script define:vars={{ productSingular: t.shop.productSingular, productPlural: t.shop.productPlural, unitFirst: lang === "en" }}>
// WICHTIG: In Layout.astro läuft <ClientRouter fallback="swap" /> (Astro View Transitions) für
// die ganze Seite. Bei einem clientseitigen Seitenwechsel (Link-Klick statt Hard-Reload) werden
// Inline-<script>-Tags NICHT erneut ausgeführt — nur beim allerersten Laden. Deshalb (genau wie
// in Layout.astro) die komplette Initialisierung in "astro:page-load" kapseln, das zuverlässig
// sowohl beim ersten Laden als auch nach jedem ClientRouter-Seitenwechsel feuert. Sonst würden
// die Klick-Listener der beiden eigenen Dropdowns (Kategorie/Mindestbewertung) nie angehängt,
// wenn man per Link (statt Direktaufruf) auf /shop/ navigiert.
document.addEventListener("astro:page-load", () => {
const grid = document.getElementById("product-grid"); const grid = document.getElementById("product-grid");
const slots = Array.from(grid.querySelectorAll(".product-slot")); const slots = Array.from(grid.querySelectorAll(".product-slot"));
const kategorieSel = document.getElementById("f-kategorie"); const kategorieSel = document.getElementById("f-kategorie");
@@ -242,11 +250,17 @@ const t = useTranslations(lang);
// hier nutzt define:vars und darf deshalb selbst kein "import" enthalten (siehe unten). // hier nutzt define:vars und darf deshalb selbst kein "import" enthalten (siehe unten).
window.__shopApply = apply; window.__shopApply = apply;
apply(); apply();
});
</script> </script>
<script> <script>
import { lokaleBewertungenFuer } from "../../../scripts/reviews"; import { lokaleBewertungenFuer } from "../../../scripts/reviews";
// Siehe Kommentar im ersten Skript oben: wegen <ClientRouter fallback="swap" /> in Layout.astro
// muss auch dieses Modul-Skript bei jedem Seitenwechsel erneut laufen, nicht nur beim ersten
// Laden — deshalb ebenfalls in einen eigenen "astro:page-load"-Handler gekapselt. Der Import
// bleibt bewusst außerhalb des Listeners (Modul-Imports müssen top-level stehen).
document.addEventListener("astro:page-load", () => {
// Lokal auf diesem Gerät gespeicherte Kundenrezensionen (siehe scripts/reviews.ts) in // Lokal auf diesem Gerät gespeicherte Kundenrezensionen (siehe scripts/reviews.ts) in
// data-bewertung einrechnen und danach neu filtern/sortieren — sonst würden der // data-bewertung einrechnen und danach neu filtern/sortieren — sonst würden der
// Mindestbewertung-Filter und die Sortierung "Beste Bewertung" neue Rezensionen ignorieren. // Mindestbewertung-Filter und die Sortierung "Beste Bewertung" neue Rezensionen ignorieren.
@@ -262,4 +276,5 @@ const t = useTranslations(lang);
slot.dataset.bewertung = String(summe / (basisAnzahl + lokale.length)); slot.dataset.bewertung = String(summe / (basisAnzahl + lokale.length));
}); });
(window as any).__shopApply?.(); (window as any).__shopApply?.();
});
</script> </script>
+15
View File
@@ -128,6 +128,14 @@ const t = useTranslations(lang);
</Layout> </Layout>
<script define:vars={{ productSingular: t.shop.productSingular, productPlural: t.shop.productPlural, unitFirst: lang === "en" }}> <script define:vars={{ productSingular: t.shop.productSingular, productPlural: t.shop.productPlural, unitFirst: lang === "en" }}>
// WICHTIG: In Layout.astro läuft <ClientRouter fallback="swap" /> (Astro View Transitions) für
// die ganze Seite. Bei einem clientseitigen Seitenwechsel (Link-Klick statt Hard-Reload) werden
// Inline-<script>-Tags NICHT erneut ausgeführt — nur beim allerersten Laden. Deshalb (genau wie
// in Layout.astro) die komplette Initialisierung in "astro:page-load" kapseln, das zuverlässig
// sowohl beim ersten Laden als auch nach jedem ClientRouter-Seitenwechsel feuert. Sonst würden
// die Klick-Listener der beiden eigenen Dropdowns (Kategorie/Mindestbewertung) nie angehängt,
// wenn man per Link (statt Direktaufruf) auf /shop/ navigiert.
document.addEventListener("astro:page-load", () => {
const grid = document.getElementById("product-grid"); const grid = document.getElementById("product-grid");
const slots = Array.from(grid.querySelectorAll(".product-slot")); const slots = Array.from(grid.querySelectorAll(".product-slot"));
const kategorieSel = document.getElementById("f-kategorie"); const kategorieSel = document.getElementById("f-kategorie");
@@ -251,11 +259,17 @@ const t = useTranslations(lang);
// hier nutzt define:vars und darf deshalb selbst kein "import" enthalten (siehe unten). // hier nutzt define:vars und darf deshalb selbst kein "import" enthalten (siehe unten).
window.__shopApply = apply; window.__shopApply = apply;
apply(); apply();
});
</script> </script>
<script> <script>
import { lokaleBewertungenFuer } from "../../scripts/reviews"; import { lokaleBewertungenFuer } from "../../scripts/reviews";
// Siehe Kommentar im ersten Skript oben: wegen <ClientRouter fallback="swap" /> in Layout.astro
// muss auch dieses Modul-Skript bei jedem Seitenwechsel erneut laufen, nicht nur beim ersten
// Laden — deshalb ebenfalls in einen eigenen "astro:page-load"-Handler gekapselt. Der Import
// bleibt bewusst außerhalb des Listeners (Modul-Imports müssen top-level stehen).
document.addEventListener("astro:page-load", () => {
// Lokal auf diesem Gerät gespeicherte Kundenrezensionen (siehe scripts/reviews.ts) in // Lokal auf diesem Gerät gespeicherte Kundenrezensionen (siehe scripts/reviews.ts) in
// data-bewertung einrechnen und danach neu filtern/sortieren — sonst würden der // data-bewertung einrechnen und danach neu filtern/sortieren — sonst würden der
// Mindestbewertung-Filter und die Sortierung "Beste Bewertung" neue Rezensionen ignorieren. // Mindestbewertung-Filter und die Sortierung "Beste Bewertung" neue Rezensionen ignorieren.
@@ -271,4 +285,5 @@ const t = useTranslations(lang);
slot.dataset.bewertung = String(summe / (basisAnzahl + lokale.length)); slot.dataset.bewertung = String(summe / (basisAnzahl + lokale.length));
}); });
(window as any).__shopApply?.(); (window as any).__shopApply?.();
});
</script> </script>