Sticky elements
How to create a sticky element that stops when it reaches another specified waypoint (element)
by hellosze
HTML
<script src="http://imakewebthings.com/jquery-waypoints/waypoints.js"></script>
<script src="http://imakewebthings.com/jquery-waypoints/shortcuts/sticky-elements/waypoints-sticky.js"></script>
<article>This element will be sticky (pos:fixed) when we scroll past it. When scrolling back up it will return as it was before.<br/>It will not scroll past the green footer. More on <a href="http://codesandnotes.com/sticky-elements/" target="_blank">Codes & Notes: Sticky elements/</a></article>
<footer></footer>
CSS
body {
/*extra space to test scrolling*/
margin: 100px 0 1000px;
}
/* This is our sticky element*/
article {
width: 60%;
z-index: 2;
background:pink;
}
/* This class gets applied by JavaScript */
.sticky {
position: fixed;
background: red;
right: 0;
top: 0;
}
/* The scripts also wraps the element in this to avoid jumpy behaviour when switching to pos: fixed */
.article-sticky-wrapper {}
/* This is our element that will stop the sticky element from scrolling */
footer {
margin-top: 300px;
height: 300px;
width:100%;
z-index: 1;
position: relative;
background:green;
}
JavaScript
var stickyElement = function () {
// element to be sticky
var $stickyEl = $("article");
// element that will stop the sticky element
var $stopEl = $('footer');
$stickyEl.waypoint('sticky', {
wrapper: '<div class="article-sticky-wrapper" />',
stuckClass: 'sticky',
offset: -1
});
$stopEl.waypoint(function (direction) {
if (direction == 'down') {
// when scrolling down
// replace pos:fixed with absolute and set top value to
// the distance from $stopEl to viewport top minus the
// height of the stickyElement
var footerOffset = $stopEl.offset();
$stickyEl.css({
position: 'absolute',
top: footerOffset.top - $stickyEl.outerHeight()
});
} else if (direction == 'up') {
// remove the inline styles so sticky styles apply again
$stickyEl.attr('style', '');
}
}, {
// trigger the waypoint when the bottom of stickyEl touches top of stopEl
offset: function () {
return $stickyEl.outerHeight();
}
});
};
stickyElement();