Jquery Waypoints Refresh

user1258303 picture user1258303 · May 4, 2012 · Viewed 10.4k times · Source

I'm working on a page that uses waypoints to create a sticky div that scrolls down the page with position: fixed until it reaches the bottom of its parent div. The code im using works as intended until $.waypoints('refresh') is called then the sticky div jumps back to the top of the page and loses its fixed position.

Heres the code:

$('#content').waypoint(function(event, direction){
if (direction === 'down') {
    $(this).removeClass('sticky').addClass('bottomed');
}
else {
    $(this).removeClass('bottomed').addClass('sticky');
}
}, {
    offset: function() {
    return $('#leftCol').outerHeight() - $('#content').outerHeight();
}

}).find('#leftCol').waypoint(function(event, direction) {
    $(this).parent().toggleClass('sticky', direction === "down");
    event.stopPropagation();
         });        

Where #leftCol is the div that scrolls down the page and #content is its parent div.

The css I have is:

#content {
width: 975px;
height: auto;
position: relative;
margin-top: 10px;
margin-bottom: 20px;
min-height: 800px;
}

#leftCol {
position: absolute;
width: 974px;
}

.sticky #leftCol {
position:fixed !important;
top:0 !important;
left: 50% !important;
width: 974px !important;
margin-left: -488px;
}

.bottomed #leftCol {
position: absolute !important;
bottom: 0px;
}

Any ideas on how to maintain the position of #leftCol when $.waypoints('refresh') is called would be much appreciated.

Thanks

Answer

imakewebthings picture imakewebthings · May 4, 2012

Do not, do not, do not ever use the fixed position element as the waypoint. See all of the following closed issues on GitHub: #64, #44, #32, #26, #24, #13, #10, #4.

This is easily the most misunderstood thing about Waypoints, and is absolutely my fault in not communicating how Waypoints works well enough. I plan to make this much clearer in the next iteration of the plugin.

For anybody wondering: Waypoints works by looking at an element's page offset. But a fixed position element's page offset is constantly changing as the user scrolls. So whenever refresh is called, be it manually, by adding another waypoint, or by resizing the browser, the location of that waypoint changes to match wherever the user is at in the page scroll at the time. What you want is a normal static position element that doesn't leave the document flow to be the waypoint. In the example I give on the Waypoints project site, the waypoint is a wrapper element that stays in place, while the nav it wraps gains and loses fixed positioning via CSS. It's very easy for somebody that doesn't understand page offsets and CSS to do what the OP has done here, as it looks intuitive. Again this is something that will be addressed more directly in the documentation/examples in the future.