Sticky Scroll
A scrolling container with panels that snap to view when scrolled. This is meant to work alongside native inertial scrolling as seen in mobile devices.
by Kyle Falconer
February 19, 2013
HTML
<script src="http://closure-library.googlecode.com/svn/trunk/closure/goog/base.js"></script>
<div id="wrapper">
<div id="container">
<div><p>0</p></div>
<div><p>1</p></div>
<div><p>2</p></div>
<div><p>3</p></div>
<div><p>4</p></div>
<div><p>5</p></div>
<div><p>6</p></div>
<div><p>7</p></div>
<div><p>8</p></div>
<div><p>9</p></div>
</div>
</div>
<div id="status_scroll"></div>
<div id="status_touch"></div>
<script>
function main() {
//window.console.clear();
window.console.log('main');
var p = new PanelView();
p.init(document.getElementById('container'));
// p.scrollToPanel(4);
}
main();
</script>
CSS
body {
background: #ddd;
}
#wrapper{
position:absolute;
top:0;
left:0;
width: 100%;
height: 100%;
overflow-x:scroll;
overflow-y:hidden;
}
#container {
height:100%;
width: 100%;
}
#container > div {
/*width: 397px;
height: 390px;*/
background-color:#dddddd;
height: 100%;
border: .5px solid #ff0000;
float: left;
}
#container > div p{
font-size:150px;
color:#383838;
margin-left:auto;
margin-right:auto;
height:150px;
width:120px;
margin-top:40%;
margin-bottom:40%
}
#status_scroll, #status_touch {
position: fixed;
display:block;
height:100px;
width:200px;
font-size:20px;
color:#3859AC;
}
#status_scroll{top:20px;
left:100px;}
#status_touch{top:20px;
left:400px;}
JavaScript
goog.require('goog.dom');
goog.require('goog.fx');
goog.require('goog.fx.dom');
goog.require('goog.fx.easing');
goog.require('goog.style');
goog.require('goog.events');
var PanelView = function() {};
PanelView.prototype.init = function(container) {
this.container = container;
this.wrapper = container.parentElement;
this.notTouching = true;
this.stopTheWorld = false;
this.status_scroll = document.getElementById('status_scroll');
this.status_touch = document.getElementById('status_touch');
this.panels = goog.dom.getChildren(container);
this.numPanels = this.panels.length;
this.wrapper.style.width = ((this.numPanels) * 100) + '%';
this.panelWidth_pct = 1 / (this.panels.length);
for (var i = 0; i < this.numPanels; i++) {
this.panels[i].style.width = this.panelWidth_pct * 100 + '%';
};
this.TotalWidth = goog.style.getSize(this.container).width;
this.panelWidth_px = Math.floor(this.panelWidth_pct * this.TotalWidth);
var self = this;
this.scrollingTimeout = null;
this.scrollingCallback = null;
this.OldScrollX = 0;
goog.events.listen(window, ['mousedown', 'touchstart'], function(evt) {
self.status_touch.innerHTML = 'TOUCHSTART';
self.status_scroll.innerHTML = '';
self.notTouching = false;
}, true);
goog.events.listen(window, ['mouseup', 'touchend', 'touchcancel'], function(evt) {
self.status_touch.innerHTML = '';
self.notTouching = true;
self.scrollingTimeout = setTimeout(function() {
self.snapToNearest();
}, 75);
}, true);
goog.events.listen(window, 'scroll', function(evt) {
if (self.stopTheWorld || !self.notTouching) {
if (self.scrollingTimeout) {
clearTimeout(self.scrollingTimeout);
}
return;
}
var dScroll = Math.abs(window.scrollX - self.OldScrollX);
self.status_scroll.innerHTML += '<br/>SCROLLING :' +...