8

I try to create a fixed div element when the scroll position is between two div elements. I use this code to create the fixed element:

var sidebar = $('.sidebar').offset().top;

$(window).scroll(function() {  
    if ($(window).scrollTop() > sidebar) {
        $('.sidebar').addClass('fixed');
    }else{
        $('.sidebar').removeClass('fixed');
    }
});

I don't know how to remove the fixed class when the blue div reached. I tried to get the current position of the blue div and add it to the if statement: var blueDiv = $('.bottom').offset().top:

if ($(window).scrollTop() > sidebar && $(window).scrollTop() < blueDiv ){
    // add fixed class
}else{
    // remove fixed class
}

Fiddle: https://jsfiddle.net/L7p5yeet/

Appel
  • 497
  • 5
  • 13
  • Appel, in your fiddle you state `If you reached the blue div (bottom)`. Does this imply reaching the bottom of the blue div, or that the blue div is the bottom of the whole part? In other words, does the sidebar needs to be fixed as soon as it reaches the top or the bottom of the blue div? – Douwe de Haan May 29 '17 at 07:47
  • 1
    What I meant with 'bottom' was the class of the blue div, not the bottom of it. Sorry, I was not clear. But thanks for you answer, it works perfect for me @DouwedeHaan! – Appel May 29 '17 at 07:52
  • No problem! It caused some confusion, but you cleared that! – Douwe de Haan May 29 '17 at 07:53
  • for info, CSS brings the position:sticky, which seems very close to the behavior you look for .There is also javascript polyfills where this is not implemented. plain css example https://codepen.io/anon/pen/XRwoRv – G-Cyrillus May 29 '17 at 08:01
  • @GCyrillus I saw this indeed. But I can't figure out how it works. The sticky position is not working.. – Appel May 29 '17 at 14:39

2 Answers2

4

You forgot to include the height of the sidebar when you checked if the sidebar already reached the blue div:

var sidebar = $('.sidebar').position().top;
var blueDiv = $('.bottom').position().top - $('.sidebar').innerHeight();

$(window).scroll(function() {
    var sT = $(window).scrollTop();
    if (sT > sidebar && sT < blueDiv) {
        $('.sidebar').addClass('fixed');
    }else{
        $('.sidebar').removeClass('fixed');
    }
});
Douwe de Haan
  • 6,247
  • 1
  • 30
  • 45
4

var sidebar = $('.sidebar').offset().top;
var blueOffset = $('.bottom').offset().top;
var sidebarHeight = $('.sidebar').height();
// If you reached the blue div (bottom), remove the 'fixed' class. Because the fixed element may not scroll over the footer or blue div. If you scroll back to the top (before the blue div or between the sidebar and the blue div) the fixed class need to be added again.
$(window).scroll(function() {
  if ($(window).scrollTop() > sidebar) {
    $('.sidebar').addClass('fixed');
  } else {
    $('.sidebar').removeClass('fixed');
  }
  if ($(window).scrollTop() > blueOffset - sidebarHeight) {
    $('.sidebar').removeClass('fixed');
  }
});
body {
  margin: 0;
  padding: 0;
}

.fixed {
  position: fixed;
  width: inherit;
  overflow: hidden;
  background: red;
  top: 0;
}

.topbar {
  background: red;
  height: 85px;
  text-align: center;
  line-height: 85px;
  color: #fff;
}

.container {
  width: 100%;
  overflow: hidden;
}

.left {
  float: left;
  width: 75%;
  background: gray;
  height: 800px;
}

.right {
  float: left;
  width: 25%;
  background: black;
  color: #fff;
}

.bottom {
  width: 100%;
  background: blue;
  overflow: hidden;
  height: 200px;
  line-height: 200px;
  color: #fff;
  text-align: center;
}

.footer {
  height: 600px;
  color: #000;
  text-align: center;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="topbar">
  <p>
    A simple topbar
  </p>
</div>
<div class="container">
  <div class="left">
    <p>
      Start fixed element
    </p>
  </div>
  <div class="right">
    <div class="sidebar">
      <ul>
        <li>Menu item 1</li>
        <li>Menu item 1</li>
      </ul>
    </div>
  </div>
  <div class="bottom">
    <p>
      Remove fixed element
    </p>
  </div>
</div>
<div class="footer">
  <p>
    A simple footer
  </p>
</div>
Saeed Ahmadian
  • 1,112
  • 1
  • 10
  • 21