xref: /plugin/combo/resources/snippet/js/menubar-fixed-top.js (revision e0122bf504b19841945ddeb5e12106ea7cfc77bf)
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