Instantly share code, notes, and snippets.
Last active
August 29, 2015 14:14
-
Star
(0)
0
You must be signed in to star a gist -
Fork
(0)
0
You must be signed in to fork a gist
-
Save teledirigido/2f460705c218d814f9d4 to your computer and use it in GitHub Desktop.
Sticky sidebar.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* 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