// Modified from http://jqueryui.com/demos/slider/#side-scroll
$(function() {
//scrollpane parts
var scrollSpeed = 150, // time in ms to delay (smaller is faster)
scrollPane = $(".scroll-pane"),
scrollContent = $(".scroll-content"),
repeat, p = scrollPane.width(),
c = scrollContent.width(),
iw = $(".scroll-content-item").outerWidth(true),
// repeat scroll while holding down button
repeater = function(b) {
scrollContent.css("margin-left", function(i, v) {
var v = parseInt(v, 10) + (b ? iw : -iw);
v = v < -c + p ? -c + p : v > 0 ? 0 : v;
return v + 'px';
});
resetValue();
repeat = setTimeout(function() {
repeater(b);
}, scrollSpeed);
};
// make buttons
scrollPane.find('button').button().bind('mousedown', function() {
repeater($(this).is('.left'));
}).bind('mouseup mouseleave', function() {
clearTimeout(repeat);
});
//build slider
var scrollbar = $(".scroll-bar").slider({
slide: function(event, ui) {
if (c > p) {
scrollContent.css("margin-left", Math.round(
ui.value / 100 * (p - c)) + "px");
} else {
scrollContent.css("margin-left", 0);
}
}
});
//append icon to handle
var handleHelper = scrollbar.find(".ui-slider-handle").mousedown(function() {
scrollbar.width(handleHelper.width());
}).mouseup(function() {
scrollbar.width("100%");
}).append("<span class='ui-icon ui-icon-grip-dotted-vertical'></span>").wrap("<div class='ui-handle-helper-parent'></div>").parent();
//change overflow to hidden now that slider handles the scrolling
scrollPane.css("overflow", "hidden");
//size scrollbar and handle proportionally to scroll distance
function sizeScrollbar() {
var remainder = c - p;
var proportion = remainder / c;
var handleSize = p - (proportion * p);
scrollbar.find(".ui-slider-handle").css({
width: handleSize,
"margin-left": -handleSize / 2
});
handleHelper.width("").width(scrollbar.width() - handleSize);
}
//reset slider value based on scroll content position
function resetValue() {
var remainder = p - c;
var leftVal = scrollContent.css("margin-left") === "auto" ? 0 : parseInt(scrollContent.css("margin-left"));
var percentage = Math.round(leftVal / remainder * 100);
scrollbar.slider("value", percentage);
}
//if the slider is 100% and window gets larger, reveal content
function reflowContent() {
var showing = c + parseInt(scrollContent.css("margin-left"), 10);
var gap = p - showing;
if (gap > 0) {
scrollContent.css("margin-left", parseInt(scrollContent.css("margin-left"), 10) + gap);
}
}
//change handle position on window resize
$(window).resize(function() {
p = scrollPane.width();
c = scrollContent.width();
resetValue();
sizeScrollbar();
reflowContent();
});
//init scrollbar size
setTimeout(sizeScrollbar, 10); //safari wants a timeout
});
<div class="demo">
<div class="scroll-pane ui-widget ui-widget-header ui-corner-all">
<div class="scroll-content">
<div class="scroll-content-item ui-widget-header">1</div>
<div class="scroll-content-item ui-widget-header">2</div>
<div class="scroll-content-item ui-widget-header">3</div>
<div class="scroll-content-item ui-widget-header">4</div>
<div class="scroll-content-item ui-widget-header">5</div>
<div class="scroll-content-item ui-widget-header">6</div>
<div class="scroll-content-item ui-widget-header">7</div>
<div class="scroll-content-item ui-widget-header">8</div>
<div class="scroll-content-item ui-widget-header">9</div>
<div class="scroll-content-item ui-widget-header">10</div>
<div class="scroll-content-item ui-widget-header">11</div>
<div class="scroll-content-item ui-widget-header">12</div>
<div class="scroll-content-item ui-widget-header">13</div>
<div class="scroll-content-item ui-widget-header">14</div>
<div class="scroll-content-item ui-widget-header">15</div>
<div class="scroll-content-item ui-widget-header">16</div>
<div class="scroll-content-item ui-widget-header">17</div>
<div class="scroll-content-item ui-widget-header">18</div>
<div class="scroll-content-item ui-widget-header">19</div>
<div class="scroll-content-item ui-widget-header">20</div>
</div>
<button class="left">←</button>
<div class="scroll-bar-wrap ui-widget-content ui-corner-bottom">
<div class="scroll-bar"></div>
</div>
<button>→</button>
</div>
<p>Holding down buttons will repeat the scroll</p>
</div>
body {
background: #222;
color: #eee;
}
.demo, .demo-description {
width:500px;
margin:0 auto;
}
.demo p {
text-align: center;
}
#demo-frame > div.demo {
padding:10px !important;
}
.scroll-pane {
overflow:auto;
width:99%;
float:left;
margin: 20px auto;
}
.scroll-content {
width:2440px;
float:left;
}
.scroll-content-item {
width:100px;
height:100px;
float:left;
font-size:3em;
line-height:96px;
text-align:center;
margin:10px;
}
* html .scroll-content-item {
display:inline;
}
.scroll-pane button.ui-button {
float:left;
height:2.1em;
margin:0 2px;
}
.scroll-bar-wrap {
float:left;
width:75%;
margin:0 -1px -1px;
padding:0 4px 0 2px;
}
.scroll-bar-wrap .ui-slider {
background:none;
border:0;
height:2em;
margin:0 auto;
}
.scroll-bar-wrap .ui-handle-helper-parent {
position:relative;
width:100%;
height:100%;
margin:0 auto;
}
.scroll-bar-wrap .ui-slider-handle {
top:.2em;
height:1.5em;
}
.scroll-bar-wrap .ui-slider-handle .ui-icon {
position:relative;
top:50%;
margin:-8px auto 0;
}