Last active
December 30, 2015 08:39
-
-
Save DutchKevv/7803702 to your computer and use it in GitHub Desktop.
A javascript sticky bar (floating sidebar) plugin. Requires jQuery and lodash/underscore
This file contains hidden or 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
(function (window, document, App, $, _) { | |
'use strict'; | |
App.prototype.Components || (App.prototype.Components = {}); | |
var supports3d = false, | |
prefixes = ['Webkit', 'Moz', 'ms', 'O'], | |
div = document.createElement('div'); | |
if (typeof div.style.perspective !== 'undefined') { | |
supports3d = true; // Browser supports CSS transform 3d without prefix | |
} else { | |
for ( var i = 0; i < prefixes.length; ++i ) { | |
if ((prefixes[i] + "Perspective") in div.style) { | |
supports3d = true; | |
break; | |
} | |
} | |
} | |
var StickyBar = function (obj) { | |
this.$el = obj.$el; | |
this.el = obj.$el[0]; | |
this.headerH = $('header').height() || 0; | |
this.footerH = $('footer').height() || 0; | |
this.isDefault = true; | |
this.isAtBottom = false; | |
this.isAtTop = false; | |
this.timeout = false; | |
this.offsetBottom = obj.offsetBottom || 100; | |
// Set transitions. | |
if (supports3d) { | |
this.el.style.WebkitTransition = '-webkit-transform 200ms linear'; | |
this.el.style.MozTransition = '-moz-transform 200ms linear'; | |
this.el.style.MsTransition = '-ms-transform 200ms linear'; | |
this.el.style.transition = 'transform 200ms linear'; | |
} | |
document.addEventListener('scroll', this.onScroll.bind(this), false); | |
}; | |
StickyBar.prototype.toDefault = function () { | |
this.isAtBottom = this.isAtTop = false; | |
this.isDefault = true; | |
this.animate(0); | |
}; | |
StickyBar.prototype.holdOnTop = function (pos) { | |
this.isAtTop = true; | |
this.isDefault = this.isAtBottom = false; | |
this.animate(pos); | |
}; | |
StickyBar.prototype.holdSteady = function () { | |
this.isDefault = this.isAtBottom = this.isAtTop = false; | |
}; | |
StickyBar.prototype.holdOnBottom = function (pos) { | |
this.isAtBottom = true; | |
this.isDefault = this.isAtTop = false; | |
this.animate(pos); | |
}; | |
StickyBar.prototype.animate = function (pos) { | |
if (supports3d) { | |
var t = 'translate3d(0,' + pos + 'px,0)'; | |
this.el.style.WebkitTransform = t; | |
this.el.style.MozTransform = t; | |
this.el.style.MsTransform = t; | |
this.el.style.transform = t; | |
} else { | |
// TODO: Set right animation. | |
} | |
}; | |
StickyBar.prototype.onScroll = _.debounce(function () { | |
var $el = this.$el, | |
windowH = _SF.prototype.windowH, | |
scrollPos = _SF.prototype.scrollTop, | |
barOffset = $el.offset().top, | |
barH = $el.height(), | |
dir = _SF.prototype.scrollDir; | |
// Parent is just as long as sidebar, so do nothing at all. | |
if (barH >= $el.parent().height()) { | |
if (!this.isDefault) { | |
this.toDefault(); | |
} | |
} | |
// Scroll bar is @ top of page OR bar fits in screen completely | |
else if (!this.isDefault && scrollPos <= this.headerH || barH < (windowH - this.headerH - this.footerH)) { | |
this.toDefault(); | |
} | |
// Bar is hanging @ bottom/top and user is scrolling up/down | |
else if ((dir === 'up' && this.isAtBottom) || (dir === 'down' && this.isAtTop)) { | |
this.holdSteady(); | |
} | |
// User is scrolling THROUGH the content and the BOTTOM of the bar is reached | |
else if (dir === 'down' && (scrollPos + windowH) > (barOffset + barH)) { | |
this.holdOnBottom(scrollPos + windowH - barH - 340); | |
} | |
// User is scrolling THROUGH the content and the TOP of the bar is reached | |
else if (dir === 'up' && (scrollPos + this.headerH) <= barOffset) { | |
this.holdOnTop(scrollPos); | |
} | |
// memory cleanup. | |
$el = windowH = scrollPos = barOffset = barH = dir = null; | |
return false; | |
}, 100); | |
App.prototype.Components.StickyBar = StickyBar; | |
})(window, document, _SF, $, _); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Use like this:
var floatingBar = new App.Compontents.StickyBar ($('#sidebarContainer'));