Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
/*!
* jQuery Floating Scrollbar - v0.5 - 09/05/2013
* http://benalman.com/
*
* Copyright (c) 2011 "Cowboy" Ben Alman
* Dual licensed under the MIT and GPL licenses.
* http://benalman.com/about/license/
*/
(function($, window){
'use strict';
var // A few reused jQuery objects.
win = $(window),
// All the elements being monitored.
elems = $([]),
// The current element.
current,
// The previous current element.
previous,
// Create the floating scrollbar.
scroller = $('<div id="floating-scrollbar"><div/></div>'),
scrollerInner = scroller.children();
// Hide or show the floating scrollbar.
function setState( state ) {
scroller.toggle(!!state);
}
// Sync floating scrollbar if element content is scrolled.
function scrollCurrent() {
if ( current ) {
scroller.scrollLeft(current.scrollLeft());
}
}
// This is called on window scroll or resize, or when elements are added or
// removed from the internal elems list.
function update() {
previous = current;
current = null;
// Find the first element whose content is visible, but whose bottom is
// below the viewport.
elems.each(function(){
var elem = $(this),
top = elem.offset().top,
bottom = top + elem.height(),
viewportBottom = win.scrollTop() + win.height(),
topOffset = 30;
if ( top + topOffset < viewportBottom && bottom > viewportBottom ) {
current = elem;
return false;
}
});
// Abort if no elements were found.
if ( !current ) { setState(); return; }
// Test to see if the current element has a scrollbar.
var scroll = current.scrollLeft(),
scrollMax = current.scrollLeft(90019001).scrollLeft(),
widthOuter = current.innerWidth(),
widthInner = widthOuter + scrollMax;
current.scrollLeft(scroll);
// Abort if the element doesn't have a scrollbar.
if ( widthInner <= widthOuter ) { setState(); return; }
// Show the floating scrollbar.
setState(true);
// Sync floating scrollbar if element content is scrolled.
if ( !previous || previous[0] !== current[0] ) {
if ( previous ) {
previous.unbind('scroll', scrollCurrent);
}
current.scroll(scrollCurrent).after(scroller);
}
// Adjust the floating scrollbar as-necessary.
scroller
.css({
left: current.offset().left - win.scrollLeft(),
width: widthOuter
})
.scrollLeft(scroll);
scrollerInner.width(widthInner);
}
// Initialize the floating scrollbar.
scroller
.hide()
.css({
position: 'fixed',
bottom: 0,
height: '30px',
overflowX: 'auto',
overflowY: 'hidden'
})
.scroll(function() {
// If there's a current element, set its scroll appropriately.
if ( current ) {
current.scrollLeft(scroller.scrollLeft());
}
});
scrollerInner.css({
border: '1px solid #fff',
opacity: 0.01
});
// Call on elements to monitor their position and scrollness. Pass `false` to
// stop monitoring those elements.
$.fn.floatingScrollbar = function( state ) {
if ( state === false ) {
// Remove these elements from the list.
elems = elems.not(this);
// Stop monitoring elements for scroll.
this.unbind('scroll', scrollCurrent);
if ( !elems.length ) {
// No elements remain, so detach scroller and unbind events.
scroller.detach();
win.unbind('resize scroll', update);
}
} else if ( this.length ) {
// Don't assume the set is non-empty!
if ( !elems.length ) {
// Adding elements for the first time, so bind events.
win.resize(update).scroll(update);
}
// Add these elements to the list.
elems = elems.add(this);
}
// Update.
update();
// Make chainable.
return this;
};
// Call this to force an update, for instance, if elements were inserted into
// the DOM before monitored elements, changing their vertical position.
$.floatingScrollbarUpdate = update;
})(jQuery, this);
/*
* jQuery Floating Scrollbar - v0.5 - 09/05/2013
* http://benalman.com/
*
* Copyright (c) 2011 "Cowboy" Ben Alman
* Dual licensed under the MIT and GPL licenses.
* http://benalman.com/about/license/
*/
(function(d,j){var h=d(j),a=d([]),i,e,f=d('<div id="floating-scrollbar"><div/></div>'),b=f.children();function g(l){f.toggle(!!l)}function k(){if(i){f.scrollLeft(i.scrollLeft())}}function c(){e=i;i=null;a.each(function(){var s=d(this),t=s.offset().top,p=t+s.height(),r=h.scrollTop()+h.height(),q=30;if(t+q<r&&p>r){i=s;return false}});if(!i){g();return}var m=i.scrollLeft(),l=i.scrollLeft(90019001).scrollLeft(),o=i.innerWidth(),n=o+l;i.scrollLeft(m);if(n<=o){g();return}g(true);if(!e||e[0]!==i[0]){if(e){e.unbind("scroll",k)}i.scroll(k).after(f)}f.css({left:i.offset().left-h.scrollLeft(),width:o}).scrollLeft(m);b.width(n)}f.hide().css({position:"fixed",bottom:0,height:"30px",overflowX:"auto",overflowY:"hidden"}).scroll(function(){if(i){i.scrollLeft(f.scrollLeft())}});b.css({border:"1px solid #fff",opacity:0.01});d.fn.floatingScrollbar=function(l){if(l===false){a=a.not(this);this.unbind("scroll",k);if(!a.length){f.detach();h.unbind("resize scroll",c)}}else{if(this.length){if(!a.length){h.resize(c).scroll(c)}a=a.add(this)}}c();return this};d.floatingScrollbarUpdate=c})(jQuery,this);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment