Skip to content

Instantly share code, notes, and snippets.

@teledirigido
Last active August 29, 2015 14:14
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save teledirigido/2f460705c218d814f9d4 to your computer and use it in GitHub Desktop.
Save teledirigido/2f460705c218d814f9d4 to your computer and use it in GitHub Desktop.
Sticky sidebar.js
/*
* This plugin requires jquery and modernizr :)
* The goal of this plugin is to stick the sidebar on top and bottom when you scroll
* Websites examples:
* http://www.carncot.school.nz/
*
* Example:
*
* var sidebar = new cs_sidebar({
* id: '#main-sidebar',
* wrapper: 'sidebar-wrapper'
* });
* sidebar.init();
*
*/
/*
* Sidebar should follow a markup like this
*
* div#your-sidebar-id
* div.your-sidebar-wrapper
* div
* nav
* whatever-youwant
*/
/*
* This is for your CSS
*
* .sidebar-relative-on { height:auto; }
* .sidebar-relative-on.fixed { position: fixed; }
*
*/
// misc.get_viewport is required.
// I didn't code this function so credits and hugs for the author <3
var misc = {
get_viewport: function(){
var e = window, a = 'inner';
if (!('innerWidth' in window )) {
a = 'client';
e = document.documentElement || document.body;
}
return { width : e[ a+'Width' ] , height : e[ a+'Height' ] };
};
var cs_sidebar = function( options ){
this.options = options;
this.sidebar_wrapper_class = this.options.wrapper;
this.sidebar_wrapper = this.options.id + ' .' + this.sidebar_wrapper_class;
this.do_resize = function(){
var _self = this;
$(window).on('load resize', function(){
var WindowHeight = misc.get_viewport().height,
sidebarHeight = $(_self.sidebar_wrapper).outerHeight();
if( WindowHeight <= sidebarHeight ){
$(_self.options.id).css({
'min-height': sidebarHeight,
'position': 'absolute'
});
$(_self.sidebar_wrapper).addClass('sidebar-relative-on');
} else {
$(_self.options.id).removeAttr('style');
$(_self.sidebar_wrapper).removeClass('sidebar-relative-on').removeClass('fixed').removeAttr('style');
}
});
};
// IMPORTANT
// sidebar and sidebar-wrapper both require position:absolute;
this.do_resize_scrolling = function(){
var _self = this,
prevScrolly = 0;
$(window).on('scroll', function(){
if( $(_self.sidebar_wrapper + '.sidebar-relative-on').length == 0 ){
return false;
}
else {
// top of the page
var curScrolly = $(this).scrollTop(),
windowHeight = misc.get_viewport().height,
windowScrolled = curScrolly + windowHeight,
sidebar = $( _self.sidebar_wrapper + '.sidebar-relative-on' ),
sidebarHeight = sidebar.outerHeight(); // 676
// if goes down
if ( curScrolly > prevScrolly ){
// if we reach the bottom of the screen, which means if the window scrolled is greater than sidebar height and his offset
// we wanna fix the sidebar
if( windowScrolled > ( sidebarHeight + ( typeof sidebarToTop === 'undefined' ? 0 : sidebarToTop ) ) ){
// first we add fixed class to sidebar
// second we give top position the difference between the window height and the sidebar height
// sidebar.addClass('fixed').css('top', - ( $('#main-side .main-side-wrapper.relative-on.fixed').outerHeight() - windowHeight ) );
sidebar.addClass('fixed').css({
'top': - ( $( _self.sidebar_wrapper + '.sidebar-relative-on.fixed').outerHeight() - windowHeight )
});
// We save sidebar offset top
sidebarToTop = sidebar.offset().top;
} else {
// we removed fixed class and we update top with sidebar offset stored previously
sidebar.removeClass('fixed').removeAttr('style').css('top', ( typeof sidebarToTop === 'undefined' ? 0 : sidebarToTop ) );
}
// if goes up
} else {
// if sidebar offset is greater than window top
// sidebar offset was stored while we went down
if( sidebarToTop > curScrolly ){
// add fixed class to sidebar
sidebar.addClass('fixed').removeAttr('style');
// we update sidebar offset
sidebarToTop = sidebar.offset().top;
}
// if sidebar offset is less, means there's a part of the sidebar hidden, so
// we while we scroll UP we want to see it
else {
// check if has fixed class and if so we can take the current offset
if( $(_self.sidebar_wrapper + '.sidebar-relative-on.fixed').length > 0 ){
// we take current offset
sidebarToTop = $(_self.sidebar_wrapper + '.sidebar-relative-on.fixed').offset().top;
// we remove the fixed class and we set offset
sidebar.removeClass('fixed').css({
'top': sidebarToTop
});
sidebar.removeClass('fixed');
}
}
}
prevScrolly = curScrolly;
}
});
};
this.prepare_html = function(callback){
var _self = this;
// will be useful to count elements
$(_self.options.id + ' .sidebar-wrapper > *').addClass('el');
typeof callback !== 'undefined' && callback();
};
this.init = function(){
var _self = this;
_self.prepare_html(function(){
_self.do_resize();
// You can test yourself and see what happen on touch screen :)
if( !Modernizr.touch ){
_self.do_resize_scrolling();
}
});
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment