Aadhit
Aadhit

Reputation: 47

How to make sticky side bar that scrolls along with content in next js?

So I have two components, a feed and a sidebar. The sidebar has more content than it can show, so it is allowed to overflow. I want the sidebar to scroll along with the content, but stick when it reaches it ends, however the content can keep scrolling.

The concept is similar to twitter's sidebar + content type.

I found a solution in jQuery, but I really can't figure out how to write the same in Nextjs, which is what I am using.

Here is the example fiddle solution I found, can someone help me write it in react/next js ?

How do i solve this ??

This is the fiddle I found

Upvotes: 0

Views: 1879

Answers (1)

Aadhit
Aadhit

Reputation: 47

I figured out the solution myself, I wrote it in a react friendly way so people wouldn't have to break their head on it!

Here you go:

function handleScroll() {
        if(window.innerHeight <1000) {
            if(bottomVisible()) {
                document.getElementById('side').style.marginTop = ` ${ window.scrollY - sidebarRef.current.offsetHeight + window.innerHeight}px`
            } else if(topVisible()) {
                // document.getElementById('side').style.marginTop = `${window.scrollY}px`;
            } else {
                document.getElementById('side').style.marginTop = `${window.scrollY}px`;
            }
        } else {
            document.getElementById('side').style.position = 'sticky';
            document.getElementById('side').style.top = '0px'
        }
    }

    useEffect(() => {

        window.addEventListener('scroll',handleScroll);
        return () => {
            window.removeEventListener('scroll', handleScroll);
        }
    
    },[])

    function bottomVisible(){
        var rect = sidebarRef.current.getBoundingClientRect();
        if(rect.bottom <= window.innerHeight) {
            return true
        }
        return false
    }

    function topVisible() {
        var rect = sidebarRef.current.getBoundingClientRect();
        if(rect.top <= 0) {
            return true
        }
        return false;
    }

Disclaimer: SidebarRef is a ref I created for the component, and its height is 1000px hence the if-else

Upvotes: 2

Related Questions