1(function IIFE() { 2 3 let done = false; 4 let fixedMenuSelector = `.navbar[data-type="fixed-top"]`; 5 6 /** 7 * Add the target style before anchor navigation 8 */ 9 window.addEventListener("DOMContentLoaded", function () { 10 11 let fixedNavbar = document.querySelector(fixedMenuSelector) 12 if (fixedNavbar == null) { 13 return; 14 } 15 let offsetHeight = fixedNavbar.offsetHeight; 16 // correct direct navigation via fragment to heading 17 let style = document.createElement("style"); 18 style.classList.add("menubar-fixed-top") 19 // textContent and not innerText (it adds br elements) 20 style.textContent = `:target { 21 scroll-margin-top: ${offsetHeight}px; 22}`; 23 document.head.appendChild(style); 24 }) 25 26 /** 27 * We do the work after the first scroll 28 * to prevent a bad cls (content layout shift) metrics 29 * from Google search 30 */ 31 window.addEventListener("scroll", function () { 32 33 if (done) { 34 return; 35 } 36 done = true; 37 38 /** 39 * The request animation frame is there to 40 * update the class on the navbar and the padding on the 41 * body at the same time to not have any layout shift 42 */ 43 window.requestAnimationFrame(function () { 44 let fixedNavbar = document.querySelector(fixedMenuSelector) 45 if (fixedNavbar == null) { 46 return; 47 } 48 let offsetHeight = fixedNavbar.offsetHeight; 49 fixedNavbar.classList.add("fixed-top") 50 // correct body padding 51 document.body.style.setProperty("padding-top", offsetHeight + "px"); 52 }); 53 54 }); 55})(); 56