Created
February 27, 2011 18:54
-
-
Save cowboy/846423 to your computer and use it in GitHub Desktop.
jQuery Floating Scrollbar
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
/*! | |
* 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($){ | |
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(){ | |
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] ) { | |
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); | |
} | |
})(jQuery); |
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
/* | |
* 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(a){function k(){f=e,e=null,d.each(function(){var c=a(this),d=c.offset().top,f=d+c.height(),g=b.scrollTop()+b.height(),h=30;if(d+h<g&&f>g){e=c;return!1}});if(!e)i();else{var c=e.scrollLeft(),k=e.scrollLeft(90019001).scrollLeft(),l=e.innerWidth(),m=l+k;e.scrollLeft(c);if(m<=l){i();return}i(!0);if(!f||f[0]!==e[0])f&&f.unbind("scroll",j),e.scroll(j).after(g);g.css({left:e.offset().left-b.scrollLeft(),width:l}).scrollLeft(c),h.width(m)}}function j(){e&&g.scrollLeft(e.scrollLeft())}function i(a){g.toggle(!!a)}var b=a(this),c=a("html"),d=a([]),e,f,g=a('<div id="floating-scrollbar"><div/></div>'),h=g.children();g.hide().css({position:"fixed",bottom:0,height:"30px",overflowX:"auto",overflowY:"hidden"}).scroll(function(){e&&e.scrollLeft(g.scrollLeft())}),h.css({border:"1px solid #fff",opacity:.01}),a.fn.floatingScrollbar=function(a){a===!1?(d=d.not(this),this.unbind("scroll",j),d.length||(g.detach(),b.unbind("resize scroll",k))):this.length&&(d.length||b.resize(k).scroll(k),d=d.add(this)),k();return this},a.floatingScrollbarUpdate=k})(jQuery) |
hello cowboy
It doesn't work when I put the page inside an iframe
Can you tell me please, what should I do?
I want to use it in mysite on IE8, but it's not work. Can you help me.
Hi,
I found the flickering issue with IE9 and it was related to the scrollLeft. I have fixed and added the code here.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
See an example.