Skip to content

Instantly share code, notes, and snippets.

@Foragan
Forked from cowboy/jquery.ba-floatingscrollbar.js
Last active August 29, 2015 13:56
Show Gist options
  • Select an option

  • Save Foragan/9006468 to your computer and use it in GitHub Desktop.

Select an option

Save Foragan/9006468 to your computer and use it in GitHub Desktop.
/*!
* jQuery Floating Scrollbar - v0.4 - 02/28/2011
* http://benalman.com/
*
* Copyright (c) 2011 "Cowboy" Ben Alman
* Dual licensed under the MIT and GPL licenses.
* http://benalman.com/about/license/
*/
(function($, window) {
// Abort if not top window
if(window.top !== window.self) {
// Alias top window instead
$.fn.floatingScrollbar = window.top.$.fn.floatingScrollbar;
$.floatingScrollbarUpdate = window.top.$.floatingScrollbarUpdate;
return;
}
var // A few reused jQuery objects.
win = $(this),
html = $('html'),
// 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();
// 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.
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;
// Hide or show the floating scrollbar.
function setState(state) {
scroller.toggle(!!state);
}
// Sync floating scrollbar if element content is scrolled.
function scrollCurrent() {
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() {
// Find offset of current window
var elemWin = this.ownerDocument.parentWindow || this.ownerDocument.defaultView,
winOffset = 0;
if(window.top !== elemWin.self)
winOffset = window.top.$(elemWin.frameElement).offset().top;
// Test element position relative to the current viewport
var elem = $(this),
top = elem.offset().top + winOffset,
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.get(0).scrollWidth - current.get(0).clientWidth,
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]) {
previous && previous.unbind('scroll', scrollCurrent);
current.scroll(scrollCurrent);
$(window.document.body).append(scroller);
}
// Adjust the floating scrollbar as-necessary.
scroller
.css({
left: current.offset().left - win.scrollLeft(),
width: widthOuter
})
.scrollLeft(scroll);
scrollerInner.width(widthInner);
}
})(jQuery, this);
/*
* jQuery Floating Scrollbar - v0.4 - 02/28/2011
* http://benalman.com/
*
* Copyright (c) 2011 "Cowboy" Ben Alman
* Dual licensed under the MIT and GPL licenses.
* http://benalman.com/about/license/
*/
(function(d,g){function l(){a&&b.scrollLeft(a.scrollLeft())}function c(){f=a;a=null;e.each(function(){var b=this.ownerDocument.parentWindow||this.ownerDocument.defaultView,c=0;g.top!==b.self&&(c=g.top.$(b.frameElement).offset().top);var b=d(this),c=b.offset().top+c,e=c+b.height(),f=h.scrollTop()+h.height();if(c+30<f&&e>f)return a=b,!1});if(a){var c=a.scrollLeft(),k=a.get(0).scrollWidth-a.get(0).clientWidth,m=a.innerWidth(),k=m+k;a.scrollLeft(c);k<=m?b.toggle(!1):(b.toggle(!0),f&&f[0]===a[0]||(f&&f.unbind("scroll",l),a.scroll(l),d(g.document.body).append(b)),b.css({left:a.offset().left-h.scrollLeft(),width:m}).scrollLeft(c),n.width(k))}else b.toggle(!1)}if(g.top!==g.self)d.fn.floatingScrollbar=g.top.$.fn.floatingScrollbar,d.floatingScrollbarUpdate=g.top.$.floatingScrollbarUpdate;else{var h=d(this);d("html");var e=d([]),a,f,b=d('<div id="floating-scrollbar"><div/></div>'),n=b.children();b.hide().css({position:"fixed",bottom:0,height:"30px",overflowX:"auto",overflowY:"hidden"}).scroll(function(){a&&a.scrollLeft(b.scrollLeft())});n.css({border:"1px solid #fff",opacity:0.01});d.fn.floatingScrollbar=function(a){!1===a?(e=e.not(this),this.unbind("scroll",l),e.length||(b.detach(),h.unbind("resize scroll",c))):this.length&&(e.length||h.resize(c).scroll(c),e=e.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