Files
Wedding-Website/backend/static/culinary.js
T
2026-08-09 12:53:12 +00:00

52 lines
1.7 KiB
JavaScript

(() => {
const switcher = document.querySelector("[data-culinary-switch]");
if (!switcher) return;
const links = [...switcher.querySelectorAll("[data-culinary-target]")];
const sections = links
.map((link) => document.getElementById(link.dataset.culinaryTarget))
.filter(Boolean);
const reduceMotion = window.matchMedia("(prefers-reduced-motion: reduce)");
const activate = (target) => {
switcher.dataset.active = target;
links.forEach((link) => {
const selected = link.dataset.culinaryTarget === target;
link.classList.toggle("is-active", selected);
if (selected) link.setAttribute("aria-current", "true");
else link.removeAttribute("aria-current");
});
};
links.forEach((link) => {
link.addEventListener("click", (event) => {
const section = document.getElementById(link.dataset.culinaryTarget);
if (!section) return;
event.preventDefault();
activate(link.dataset.culinaryTarget);
section.scrollIntoView({
behavior: reduceMotion.matches ? "auto" : "smooth",
block: "start",
});
window.history.replaceState(null, "", link.hash);
});
});
const observer = new IntersectionObserver(
(entries) => {
const visible = entries
.filter((entry) => entry.isIntersecting)
.sort((a, b) => b.intersectionRatio - a.intersectionRatio)[0];
if (visible) activate(visible.target.id);
},
{ rootMargin: "-22% 0px -58%", threshold: [0, 0.15, 0.4] }
);
sections.forEach((section) => observer.observe(section));
const initialTarget = window.location.hash.slice(1);
if (sections.some((section) => section.id === initialTarget)) {
activate(initialTarget);
}
})();