Skip to content

Instantly share code, notes, and snippets.

@apathetic
Created November 8, 2012 00:55
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save apathetic/4035708 to your computer and use it in GitHub Desktop.
Save apathetic/4035708 to your computer and use it in GitHub Desktop.
jQuery: 3-State Sticky Column
/*
* jQuery 3-state Sticky element
* Description: sticks a DOM element to the top of viewport, unsticks when
* footer/header push it up/down
* author: wes hatch
*
*/
(function($, window, undefined){
var states = { PINNED_TOP:"pinnedTop", FLOATING:"floating", PINNED_BOTTOM:"pinnedBottom" };
var determine = {
pinnedTop:function(){
if( _viewport >= element.height && container.height > element.height) {
if( container.bottom < element.height ) {
return setState(states.PINNED_BOTTOM);
}
if (element.top < (0+topMargin) ) {
return setState(states.FLOATING);
}
}
},
floating:function(){
// put in viewportResized:
if (_viewport < element.height || container.height <= element.height) {
return setState(states.PINNED_TOP);
}
if( container.top > element.top ) {
return setState(states.PINNED_TOP);
}
if (container.bottom <= element.bottom){
return setState(states.PINNED_BOTTOM);
}
},
pinnedBottom:function(){
// put in viewportResized:
if (_viewport < element.height || container.height <= element.height) {
return setState(states.PINNED_TOP);
}
if (element.top > (0+topMargin) ) {
return setState(states.FLOATING);
}
}
};
var _viewport = $(window).height(),
_currentState = '',
_stateSwitcher,
element,
container;
var topMargin = 12;
// --------------------------------
function viewportResized (){
_viewport = $(window).height();
viewportScrolled();
}
function viewportScrolled (){
container = $('#dashboard').parent()[0].getBoundingClientRect();
element = $('#dashboard')[0].getBoundingClientRect(); // TODO use options
_stateSwitcher();
}
function setState (state){
if(_currentState == state) { return; }
$('#dashboard').removeClass(_currentState);
$('#dashboard').addClass(state);
_currentState = state;
_stateSwitcher = determine[state];
}
// --------------------------------
$.fn.stickyColumn = function(options) {
// if(Browser.Engine.trident4){ return; } // if IE6 just forget it
options = $.extend( {}, $.fn.stickyColumn.options, options );
return this.each(function () {
element = $('#dashboard')[0].getBoundingClientRect(); // TODO use options
container = $('#dashboard').parent()[0].getBoundingClientRect(); // TODO use options
setState(states.PINNED_TOP);
$(window).on({
'resize': viewportResized,
'scroll': viewportScrolled.bind(this)
});
});
}
$.fn.stickyColumn.options = {
element: '#dashboard',
container: '#main.container', // or element.parent()
topClass: 'pinnedTop',
floatClass: 'floating',
bottomClass: 'pinnedBottom',
topMargin: 0
}
})(jQuery, window);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment