Die Stelle bleibt -- auch wenn man ueber die Kopfzeile zurueckgeht

Filipe, zum vierten Mal: "muss ich jedes mal wenn ich von einer seite
zurück scrolle immer wieder runter scrollen um weiter zu schauen und
das nervt."

DIE WIEDERHERSTELLUNG GAB ES SEIT DEM 20.09. -- sorgfaeltig gebaut,
mit Warten auf die nachgeladene Hoehe, mit Aufgeben nach drei
Sekunden, mit "wer selbst scrollt, gewinnt".

SIE LIEF NUR FAST NIE. Denn sie lief ausschliesslich bei
`navigation.type === "back_forward"`, also beim Zurueck-Knopf des
Browsers. Im Haus geht man anders zurueck: ueber die Kopfzeile ("TEAM
DOGI › HIGHLIGHTS"), und dort steht ein ganz gewoehnliches
`<a href="start.html">`. Fuer den Browser ist das eine Fahrt
VORWAERTS. Die Bedingung war also falsch -- und der else-Zweig
loeschte die eben gemerkte Stelle noch dazu.

IM KOPF DERSELBEN DATEI STAND DIE LOESUNG ALS ABSICHT: "Ein eigener
Merker faengt den Fall ab, dass der Zurueck-Knopf der Kopfleiste
benutzt wurde." Gebaut wurde er nie.

UND DESHALB HAT ES IN JEDEM TEST FUNKTIONIERT: Wer mit `goBack()`
prueft, prueft den einen Weg, den niemand geht. Gemessen am 21.09.:
ueber goBack sauber wiederhergestellt, ueber den Link in der
Kopfzeile oben gelandet. Gefunden hat es Filipes Bildschirmvideo --
17 Sekunden, drei Bilder, und der Ablauf war eindeutig.

Der Merker gibt es jetzt wirklich: Beim Klick auf einen EIGENEN
Zurueck-Weg (`.zurueck`, `.zurueck-knopf`) wird das Ziel notiert; wer
dort binnen 30 Sekunden ankommt, bekommt seine Stelle zurueck. Er
gilt fuer genau eine Ankunft -- wer die Seite eine Minute spaeter
normal oeffnet, faengt wieder oben an. Und NUR fuer diese zwei
Klassen, nicht fuer jeden Link: Sonst landete man beim Oeffnen eines
Brettes mitten darin.

Dazu der Rueckwaerts-Speicher des Browsers: Holt er eine Seite aus dem
Speicher, laeuft keine Zeile mehr, und unser `manual` verbietet ihm
gleichzeitig, die Stelle selbst wiederherzustellen. Ein `pageshow`
faengt das ab. Dieser Fall ist NICHT gemessen -- in Playwright greift
der Speicher nicht -- sondern aus der Spezifikation begruendet. Das
steht auch so im Kommentar, damit niemand spaeter glaubt, er sei
nachgewiesen.

NEU: pruef-stelle.mjs, 9 Pruefungen. Sie geht beide Wege zurueck --
Kopfzeile UND Browser -- und haelt ausdruecklich fest, dass der erste
KEIN "back_forward" ist. Dazu die Gegenprobe, dass eine frisch
geoeffnete Seite oben anfaengt: Ohne sie waere alles auch dann gruen,
wenn die Seite IMMER zur alten Stelle springt, und das waere
schlimmer als das Problem.

Co-Authored-By: Claude Opus 5 <[email protected]>
This commit is contained in:
2026-09-21 14:24:19 +02:00
co-authored by Claude Opus 5
parent 9a30f9e304
commit 7305f694d5
39 changed files with 838 additions and 508 deletions
+86 -3
View File
@@ -2037,10 +2037,75 @@
});
/* Und der Zurück-Knopf der Kopfleiste: Er ruft `history.back()`, und
dabei ist `pagehide` je nach Browser zu spät dran. */
/* UNSER EIGENES ZURUECK IST FUER DEN BROWSER EIN HINGEHEN
(gebaut am 21.09.2026 -- versprochen war es seit dem 20.09.).
Im Kopf dieser Datei steht seit jeher: "Ein eigener Merker faengt
den Fall ab, dass der Zurueck-Knopf der Kopfleiste benutzt wurde."
Gebaut wurde er nie. Ein Kommentar, der eine Absicht beschreibt,
erfuellt sie nicht.
WAS DAS IN DER PRAXIS HIESS -- Filipes Video vom 21.09.: Er steht
weit unten auf der Startseite, oeffnet ein Brett, geht ueber
"TEAM DOGI" in der Kopfzeile zurueck -- und landet ganz oben. Bei
jedem Mal.
DER GRUND: Dieser Weg zurueck ist ein `<a href="start.html">`.
Fuer den Browser ist das eine NEUE Fahrt vorwaerts, nicht
`back_forward`. Die Wiederherstellung unten laeuft deshalb nicht
-- und schlimmer: Der `else`-Zweig loescht die eben gemerkte
Stelle sogar, weil "ein frisch geoeffneter Bereich faengt oben
an".
Der Browser-Zurueckknopf und der Pfeil in der Kopfleiste
(`history.back()`) waren nie betroffen. Deshalb hat es in jedem
Test funktioniert und im Alltag nie -- gemessen mit Playwright:
y=1200 sauber wiederhergestellt. Man muss den Weg gehen, den der
Mensch geht.
DER MERKER GILT NUR EINMAL UND NUR KURZ: Er nennt das Ziel und
die Zeit. Wer eine Minute spaeter dieselbe Seite normal oeffnet,
faengt wieder oben an -- wie es sein soll. */
var ZURUECK_SCHLUESSEL = 'ws-zurueck';
var ZURUECK_MS = 30000;
function zurueckMerken(ziel) {
try {
sessionStorage.setItem(ZURUECK_SCHLUESSEL,
JSON.stringify({ ziel: ziel, am: Date.now() }));
} catch (e) { /* ohne Speicher eben ohne */ }
}
/** Bin ich gerade ueber einen EIGENEN Zurueck-Weg hier gelandet?
* Verbraucht den Merker dabei -- er gilt fuer genau eine Ankunft. */
function ueberEigenesZurueck() {
var roh;
try { roh = sessionStorage.getItem(ZURUECK_SCHLUESSEL); } catch (e) { return false; }
if (!roh) return false;
try { sessionStorage.removeItem(ZURUECK_SCHLUESSEL); } catch (e) { /* egal */ }
var m;
try { m = JSON.parse(roh); } catch (e) { return false; }
if (!m || Date.now() - (m.am || 0) > ZURUECK_MS) return false;
return m.ziel === location.pathname + location.search;
}
document.addEventListener('click', function (e) {
var a = e.target && e.target.closest
var ziel = e.target && e.target.closest
&& e.target.closest('a[href], .zurueck-knopf, .zurueck');
if (a) merken();
if (!ziel) return;
merken();
/* NUR bei den Wegen, die WIRKLICH zurueckfuehren -- nicht bei
jedem Link. Sonst wuerde jede Kachel als "zurueck" gelten und
man landete beim Oeffnen eines Bretts mitten darin. */
var istZurueck = ziel.classList
&& (ziel.classList.contains('zurueck') || ziel.classList.contains('zurueck-knopf'));
if (!istZurueck) return;
var adresse = ziel.getAttribute && ziel.getAttribute('href');
if (!adresse) return; /* der Knopf nimmt history.back() -- der braucht nichts */
try {
var u = new URL(adresse, location.href);
zurueckMerken(u.pathname + u.search);
} catch (f) { /* unbrauchbare Adresse -> dann eben ohne */ }
}, true);
/* ---- Und zurück ------------------------------------------------- */
@@ -2144,7 +2209,25 @@
history.scrollRestoration = 'manual';
}
if (kamVonZurueck()) {
/* DER RUECKWAERTS-SPEICHER DES BROWSERS (21.09.2026).
Holt der Browser eine Seite aus seinem Speicher zurueck, laeuft
KEINE Zeile dieser Datei noch einmal -- und `manual` oben verbietet
ihm gleichzeitig, die Stelle selbst wiederherzustellen. Ohne diese
drei Zeilen waere die Seite dann oben, und zwar ohne dass
irgendetwas kaputt ist.
Nachgemessen: In Playwright greift der Speicher nicht (persisted
bleibt false), im echten Browser sehr wohl. Der Fall ist hier
also NICHT durch eine Messung belegt, sondern durch die
Spezifikation -- und diese Zeile kostet nichts, wenn er nie
eintritt. Das steht so da, damit niemand spaeter glaubt, es sei
nachgewiesen. */
window.addEventListener('pageshow', function (e) {
if (e && e.persisted) wiederherstellen();
});
if (kamVonZurueck() || ueberEigenesZurueck()) {
if (document.readyState === 'loading') {
document.addEventListener('DOMContentLoaded', wiederherstellen);
} else {