| |
| <?php
|
| <!-- Example: your sticky header -->
|
| <header id="site-header" style="position:sticky;top:0;height:72px;">...</header>
|
| document.addEventListener("DOMContentLoaded", () => {
|
|
|
| const HEADER_SELECTOR = "#site-header";
|
|
|
| const getHeaderOffset = () => {
|
| const header = HEADER_SELECTOR && document.querySelector(HEADER_SELECTOR);
|
| return header ? header.getBoundingClientRect().height : 0;
|
| };
|
|
|
| const prefersReduced = window.matchMedia("(prefers-reduced-motion: reduce)").matches;
|
|
|
| const scrollToTarget = (target) => {
|
| if (!target) return;
|
|
|
|
|
| const headerOffset = getHeaderOffset();
|
| const elementY = window.pageYOffset + target.getBoundingClientRect().top;
|
| const y = Math.max(elementY - headerOffset, 0);
|
|
|
| window.scrollTo({
|
| top: y,
|
| behavior: prefersReduced ? "auto" : "smooth"
|
| });
|
|
|
|
|
|
|
| target.setAttribute("tabindex", "-1");
|
| target.focus({ preventScroll: true });
|
| target.addEventListener("blur", () => target.removeAttribute("tabindex"), { once: true });
|
| };
|
|
|
|
|
| document.querySelectorAll('a[href^="#"]:not([href="#"])').forEach((anchor) => {
|
| anchor.addEventListener("click", (e) => {
|
| const id = anchor.getAttribute("href").slice(1);
|
| const target = document.getElementById(id);
|
| if (!target) return;
|
|
|
| e.preventDefault();
|
|
|
|
|
| history.pushState(null, "", `
|
| scrollToTarget(target);
|
| });
|
| });
|
|
|
|
|
| const handleHashNavigation = () => {
|
| const id = window.location.hash && window.location.hash.slice(1);
|
| if (!id) return;
|
| const target = document.getElementById(id);
|
| if (target) scrollToTarget(target);
|
| };
|
|
|
| window.addEventListener("hashchange", handleHashNavigation);
|
| handleHashNavigation();
|
| });
|
|
|
|
|
| |
| |
Comments