Daniel Scott
Daniel Scott

Reputation: 107

Scrolling fixed sidebar then unfix after scroll

I'm trying to mimic a feature

If you scroll down, there is a box on the right that follow you down the page until it reaches the footer. So it's like some sort logic that sets a window for which the side bar is fixed. Here is my code.

    var windowHeight = jQuery(window).height();
    var distanceFromTop = jQuery(window).scrollTop();

    jQuery(window).on("scroll", function(event){
        windowHeight = jQuery(window).height();
        distanceFromTop = jQuery(window).scrollTop();
        

        if (distanceFromTop > jQuery("#firstdiv").height() && distanceFromTop < jQuery("#seconddiv").height()) {
          // Lock
        } else {
          // Unlock
        }
    });

Upvotes: 1

Views: 595

Answers (1)

A Haworth
A Haworth

Reputation: 36664

You can use a combination of sticky along with an IntersectionObserver to achieve this which saves having to constantly look for whether the user is scrolling and making adjustments.

The fixed/floating box is set initially to sticky which means as you scroll down it will stick to the top of the viewport when it's there. Then an intersection observer on the footer causes the box to be set to relative ('unsticks it') so it will move up as the footer is more fully revealed. When the footer is scrolled out of sight, the box reverts to being sticky.

Here's a simple set-up to demonstrate:

function observed(entries) {
 if (entries[0].isIntersecting) {
   box.style.position = 'relative';
   box.style.top = 'calc(' + footer.offsetTop + 'px - 100vh - ' + box.parentElement.offsetTop + 'px)';
 }
 else {
   box.style.position = 'sticky';
   box.style.top = '0px';
 }
}
const box=document.querySelector('#box');
const footer = document.querySelector('footer');
const observer = new IntersectionObserver(observed);

observer.observe(footer);
header {
  width: 100vw;
  height: 30vh;
  background: cyan;
}
.content {
  width: 100%; 
  height: 200vh;
  position: relative;
}


#box {
  position: sticky;
  top: 0;
  background: pink;
  width: 20vw;
  height:10vw;
}

footer {
  height: 50vh;
  background: lime;
}
<header>HEADER</header>
<div class="content">
  <div id="box">FLOATING/FIXED BOX</div>
</div>
<footer>FOOTER</footer>

Upvotes: 2

Related Questions