Targeting position:sticky elements that are currently in a 'stuck' state

后端 未结 5 2006
名媛妹妹
名媛妹妹 2020-12-04 17:26

position: sticky works on some mobile browsers now, so you can make a menu bar scroll with the page but then stick to the top of the viewport whenever the user scrolls past

5条回答
  •  难免孤独
    2020-12-04 17:57

    Not really a fan of using js hacks for styling stuff (ie getBoudingClientRect, scroll listening, resize listening), but this is how I'm currently solving the problem. This solution will have issues with pages that have minimizable/maximizable content (

    ), or nested scrolling, or really any curve balls whatsoever. That being said, it's a simple solution for when the problem is simple as well.

    let lowestKnownOffset: number = -1;
    window.addEventListener("resize", () => lowestKnownOffset = -1);
    
    const $Title = document.getElementById("Title");
    let requestedFrame: number;
    window.addEventListener("scroll", (event) => {
        if (requestedFrame) { return; }
        requestedFrame = requestAnimationFrame(() => {
            // if it's sticky to top, the offset will bottom out at its natural page offset
            if (lowestKnownOffset === -1) { lowestKnownOffset = $Title.offsetTop; }
            lowestKnownOffset = Math.min(lowestKnownOffset, $Title.offsetTop);
            // this condition assumes that $Title is the only sticky element and it sticks at top: 0px
            // if there are multiple elements, this can be updated to choose whichever one it furthest down on the page as the sticky one
            if (window.scrollY >= lowestKnownOffset) {
                $Title.classList.add("--stuck");
            } else {
                $Title.classList.remove("--stuck");
            }
            requestedFrame = undefined;
        });
    })
    

提交回复
热议问题