diff --git a/frontend/src/components/Guide.vue b/frontend/src/components/Guide.vue index 41fefa8..43eb3a2 100644 --- a/frontend/src/components/Guide.vue +++ b/frontend/src/components/Guide.vue @@ -89,11 +89,11 @@ async function laden() { // Gemerkte Position hat Vorrang (die Adresse spiegelt nur den letzten Scrollstand); zuletzt im Lesemodus gelesen → dessen Stelle const ziel = idVonLesemodus(pos) || pos.abschnitt || idVonNr(props.nr) // Am Buchanfang (Vorwort) nicht scrollen, damit Titel und Knopfleiste sichtbar bleiben - if (ziel && ziel !== 'vorwort' && !aktiv.value) document.getElementById(ziel)?.scrollIntoView({ block: 'start' }) + if (ziel && ziel !== 'vorwort' && !aktiv.value) scrollZu(ziel) } watch(() => [props.slug, props.version], () => { aktiv.value = ''; cache.clear(); laden() }, { immediate: true }) // Zurück-Taste oder getippte Adresse: zum Abschnitt springen, wenn er nicht schon aktiv ist -watch(() => props.nr, (n) => { const id = idVonNr(n); if (id && id !== aktiv.value) { aktiv.value = id; document.getElementById(id)?.scrollIntoView({ block: 'start' }) } }) +watch(() => props.nr, (n) => { const id = idVonNr(n); if (id && id !== aktiv.value) { aktiv.value = id; scrollZu(id) } }) watch(() => props.laeuft, (l, alt) => { if (alt && !l) laden() }) // Während eines Laufs nur nachladen, wenn sich der Fortschritt geändert hat watch(() => props.fortschritt, (n, alt) => { if (props.laeuft && n !== alt) laden() }) @@ -135,10 +135,19 @@ function spy() { }, { root: lese.value, rootMargin: '0px 0px -75% 0px' }) document.querySelectorAll('.buch [data-spy]').forEach((el) => beobachter.observe(el)) } +// Zum Element scrollen, abzüglich der Höhe der festen Knopfleiste (Mobil), damit die Überschrift sichtbar bleibt +function scrollZu(id, weich = false) { + const el = document.getElementById(id); const box = lese.value + if (!el || !box) return + const leiste = box.querySelector('.mobil-leiste') + const versatz = leiste && getComputedStyle(leiste).position === 'sticky' ? leiste.offsetHeight : 0 + const top = el.getBoundingClientRect().top - box.getBoundingClientRect().top + box.scrollTop - versatz + box.scrollTo({ top, behavior: weich ? 'smooth' : 'auto' }) +} function springe(id) { navAuf.value = false aktiv.value = id - document.getElementById(id)?.scrollIntoView({ behavior: 'smooth', block: 'start' }) + scrollZu(id, true) emit('nr', { nr: nrVonId(id), push: true }) } function taste(e) { if (e.key === 'Escape') navAuf.value = false }