52 lines
1.7 KiB
JavaScript
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);
|
|
}
|
|
})();
|