document.addEventListener("DOMContentLoaded", () => { const sections = document.querySelectorAll("main > section, body > header"); const links = document.querySelectorAll("nav a:not([target=_blank])"); const linksArray = Array.from(links); let scrollingOnClick = false; // Deactivate the observer if the scroll is on a link click // Intersection Observer const observer = new IntersectionObserver( (entries) => { if (scrollingOnClick) return; // ignore if the scroll is manual entries.forEach((entry) => { if (entry.isIntersecting) { const id = entry.target.id; const link = linksArray.find((link) => link.href.includes(`#${id}`)); linksArray.forEach((link) => link.classList.remove("active")); if (link) link.classList.add("active"); // update URL history.replaceState(null, null, `#${id}`); } }); }, { rootMargin: "-50% 0px -50% 0px" }, ); sections.forEach((section) => observer.observe(section)); // Gestion du clic sur un lien linksArray.forEach((link) => { link.addEventListener("click", (e) => { e.preventDefault(); // avoid default navigation const targetId = link.getAttribute("href").slice(1); const targetSection = document.getElementById(targetId); // deactivate observer temporarily scrollingOnClick = true; // scroll to the target targetSection.scrollIntoView({ behavior: "smooth" }); // update link state linksArray.forEach((link) => link.classList.remove("active")); link.classList.add("active"); // update URL history.replaceState(null, null, `#${targetId}`); // on scroll end, reactivate the observer const onScrollEnd = () => { scrollingOnClick = false; window.removeEventListener("scroll", onScrollEnd); // Nettoyage }; window.addEventListener("scroll", onScrollEnd); }); }); });