/* ========================================================================== Einführung als Folien (restricted/einfuehrung.php). Blättern mit den Knöpfen, den Pfeiltasten oder durch Wischen. Die Folie steht in der Adresse (#folie-7), damit man sie verlinken und nach einem Neuladen dort weitermachen kann. Eine Erklärung antippen lässt ihren Punkt im Bild aufleuchten - und umgekehrt. ========================================================================== */ document.addEventListener("DOMContentLoaded", function () { const ef = document.getElementById("einfuehrung"); if (!ef) return; const folien = [...ef.querySelectorAll(".ef-folie")]; const zurueck = ef.querySelector(".ef-zurueck"); const weiter = ef.querySelector(".ef-weiter"); const zaehler = ef.querySelector(".ef-zaehler"); const balken = ef.querySelector(".ef-fortschritt span"); const kapitelWahl = ef.querySelector(".ef-kapitel"); const punkteNav = ef.querySelector(".ef-punkte-nav"); let aktuell = 0; // Die Punkte unten: einer je Folie, Teile durch eine Lücke getrennt. folien.forEach((f, i) => { const p = document.createElement("span"); p.className = "ef-punkt" + (i > 0 && folien[i - 1].dataset.teil !== f.dataset.teil ? " neuer-teil" : ""); p.dataset.ziel = i; punkteNav.appendChild(p); }); punkteNav.removeAttribute("aria-hidden"); function zeige(nr, ohneAdresse) { nr = Math.max(0, Math.min(folien.length - 1, nr)); const richtung = nr >= aktuell ? "vor" : "rueck"; folien.forEach((f, i) => { f.hidden = i !== nr; f.classList.remove("rein-vor", "rein-rueck"); }); const f = folien[nr]; void f.offsetWidth; // Animation neu starten f.classList.add("rein-" + richtung); aktuell = nr; zaehler.textContent = (nr + 1) + " / " + folien.length; balken.style.width = ((nr + 1) / folien.length * 100).toFixed(1) + "%"; zurueck.disabled = nr === 0; weiter.innerHTML = nr === folien.length - 1 ? 'Von vorn' : 'Weiter'; ef.querySelectorAll(".ef-teil").forEach(t => t.classList.toggle("aktiv", t.dataset.teil === f.dataset.teil)); punkteNav.querySelectorAll(".ef-punkt").forEach((p, i) => p.classList.toggle("aktiv", i === nr)); // Das Kapitel dieser Folie in der Auswahl: die letzte Kapitel-Folie <= nr. let kap = null; [...kapitelWahl.options].forEach(o => { if (Number(o.value) <= nr) kap = o.value; }); if (kap !== null) kapitelWahl.value = kap; if (!ohneAdresse) history.replaceState(null, "", "#folie-" + (nr + 1)); // Auf dem Handy nach oben, damit die neue Folie mit dem Titel beginnt. const oben = ef.getBoundingClientRect().top; if (oben < 0) ef.scrollIntoView({ block: "start", behavior: "smooth" }); } zurueck.addEventListener("click", () => zeige(aktuell - 1)); weiter.addEventListener("click", () => zeige(aktuell === folien.length - 1 ? 0 : aktuell + 1)); kapitelWahl.addEventListener("change", () => zeige(Number(kapitelWahl.value))); ef.querySelectorAll(".ef-teil").forEach(t => t.addEventListener("click", () => { zeige(folien.findIndex(f => f.dataset.teil === t.dataset.teil)); })); punkteNav.addEventListener("click", e => { const p = e.target.closest(".ef-punkt"); if (p) zeige(Number(p.dataset.ziel)); }); document.addEventListener("keydown", e => { if (e.target.closest("input, select, textarea")) return; if (e.key === "ArrowRight" || e.key === "PageDown") { zeige(aktuell + 1); e.preventDefault(); } if (e.key === "ArrowLeft" || e.key === "PageUp") { zeige(aktuell - 1); e.preventDefault(); } if (e.key === "Home") zeige(0); if (e.key === "End") zeige(folien.length - 1); }); // Wischen: waagerecht deutlich, senkrecht wenig - sonst ist es Scrollen. let start = null; ef.querySelector(".ef-buehne").addEventListener("touchstart", e => { start = { x: e.touches[0].clientX, y: e.touches[0].clientY }; }, { passive: true }); ef.querySelector(".ef-buehne").addEventListener("touchend", e => { if (!start) return; const dx = e.changedTouches[0].clientX - start.x; const dy = e.changedTouches[0].clientY - start.y; start = null; if (Math.abs(dx) > 60 && Math.abs(dx) > Math.abs(dy) * 1.5) zeige(aktuell + (dx < 0 ? 1 : -1)); }, { passive: true }); // Erklärung und Punkt im Bild gehören zusammen: das eine hebt das andere hervor. function hervorheben(folie, nr, an) { folie.querySelectorAll('[data-marke="' + nr + '"]').forEach(el => el.classList.toggle("hell", an)); } folien.forEach(folie => { folie.addEventListener("mouseover", e => { const el = e.target.closest("[data-marke]"); if (el) hervorheben(folie, el.dataset.marke, true); }); folie.addEventListener("mouseout", e => { const el = e.target.closest("[data-marke]"); if (el) hervorheben(folie, el.dataset.marke, false); }); folie.addEventListener("click", e => { const el = e.target.closest("[data-marke]"); if (!el) return; const nr = el.dataset.marke; folie.querySelectorAll("[data-marke]").forEach(x => x.classList.remove("hell")); hervorheben(folie, nr, true); // Auf dem Handy liegt das Bild über dem Text: zum Punkt scrollen. const punkt = folie.querySelector('.ef-marke[data-marke="' + nr + '"]'); if (punkt && el.tagName === "LI") { const r = punkt.getBoundingClientRect(); if (r.top < 60 || r.bottom > window.innerHeight) punkt.scrollIntoView({ block: "center", behavior: "smooth" }); } }); }); // Ein Link auf eine Folie in einem schon offenen Tab ändert nur den Anker - // die Seite lädt dann nicht neu, also hier nachziehen. window.addEventListener("hashchange", () => { const t = /^#folie-(\d+)$/.exec(location.hash); if (t && Number(t[1]) - 1 !== aktuell) zeige(Number(t[1]) - 1, true); }); const treffer = /^#folie-(\d+)$/.exec(location.hash); zeige(treffer ? Number(treffer[1]) - 1 : 0, !treffer); });