Implemented support for nested scrollviews, scroll propagation, and direction locking. To make a div scrollable use:

data-scroll="x|y|true"
This commit is contained in:
Kin Blas 2010-12-01 14:04:54 -08:00
parent 9423bc199d
commit 39a9681d55
5 changed files with 1205 additions and 91 deletions

View file

@ -1,21 +1,9 @@
@charset "utf-8";
.ui-scrollview-clip {
overflow: hidden;
position: relative;
}
.ui-scrollview-view {
position: relative;
overflow: hidden;
top: 0;
left: 0;
/*
min-width: 100%;
min-height: 100%;
padding: 0;
margin: 0;
*/
}
.ui-scrolllistview .ui-li-divider {
@ -36,14 +24,14 @@
opacity: 1;
}
.ui-scrollbar-vertical {
.ui-scrollbar-y {
top: 2px;
right: 2px;
bottom: 8px;
width: 5px;
}
.ui-scrollbar-horizontal {
.ui-scrollbar-x {
right: 8px;
bottom: 2px;
left: 2px;
@ -66,12 +54,12 @@
border-radius: 2px;
}
.ui-scrollbar-vertical .ui-scrollbar-thumb {
.ui-scrollbar-y .ui-scrollbar-thumb {
width: 5px;
height: 100%;
}
.ui-scrollbar-horizontal .ui-scrollbar-thumb {
.ui-scrollbar-x .ui-scrollbar-thumb {
width: 100%;
height: 5px;
}

View file

@ -9,25 +9,32 @@
jQuery.widget( "mobile.scrollview", jQuery.mobile.widget, {
options: {
fps: 60, // Frames per second in msecs.
direction: null, // "vertical", "horizontal", or null for both.
direction: null, // "x", "y", or null for both.
scrollDuration: 2000, // Duration of the scrolling animation in msecs.
overshootDuration: 250, // Duration of the overshoot animation in msecs.
snapbackDuration: 500, // Duration of the snapback animation in msecs.
moveThreshold: 100, // Time between mousemoves must not exceed this threshold.
moveThreshold: 10, // User must move this many pixels in any direction to trigger a scroll.
moveIntervalThreshold: 100, // Time between mousemoves must not exceed this threshold.
useCSSTransform: true, // Use CSS "transform" property instead of "top" and "left" for positioning.
startEventName: "scrollstart.scrollview",
updateEventName: "scrollupdate.scrollview",
stopEventName: "scrollstop.scrollview",
startEventName: "scrollstart",
updateEventName: "scrollupdate",
stopEventName: "scrollstop",
eventType: $.support.touch ? "touch" : "mouse",
showScrollBars: true
},
_makePositioned: function($ele)
{
if ($ele.css("position") == "static")
$ele.css("position", "relative");
},
_create: function()
{
this._$clip = $(this.element).addClass("ui-scrollview-clip");
@ -36,13 +43,24 @@ jQuery.widget( "mobile.scrollview", jQuery.mobile.widget, {
$child = this._$clip.wrapInner("<div></div>").children();
}
this._$view = $child.addClass("ui-scrollview-view");
this._$clip.css("overflow", "hidden");
this._makePositioned(this._$clip);
this._$view.css("overflow", "hidden");
if (!this.options.useCSSTransform)
{
this._makePositioned(this._$view);
this._$view.css({ left: 0, top: 0 });
}
this._sx = 0;
this._sy = 0;
var direction = this.options.direction;
this._hTracker = (direction != "vertical") ? new MomentumTracker(this.options) : null;
this._vTracker = (direction != "horizontal") ? new MomentumTracker(this.options) : null;
this._hTracker = (direction != "y") ? new MomentumTracker(this.options) : null;
this._vTracker = (direction != "x") ? new MomentumTracker(this.options) : null;
this._timerInterval = 1000/this.options.fps;
this._timerID = 0;
@ -137,27 +155,21 @@ jQuery.widget( "mobile.scrollview", jQuery.mobile.widget, {
this._stopMScroll();
},
_setElementTransform: function($ele, x, y)
{
var v = "translate3d(" + x + "," + y + ", 0px)";
$ele.css({
"-moz-transform": v,
"-webkit-transform": v,
"transform": v
});
},
_setScrollPosition: function(x, y)
{
this._sx = x;
this._sy = y;
var kdebug = 0;
if (y == 0)
++kdebug;
var $v = this._$view;
var uct = this.options.useCSSTransform;
if (uct)
this._setElementTransform($v, x + "px", y + "px");
setElementTransform($v, x + "px", y + "px");
else
$v.css({left: x + "px", top: y + "px"});
@ -170,7 +182,7 @@ jQuery.widget( "mobile.scrollview", jQuery.mobile.widget, {
{
var $sbt = $vsb.find(".ui-scrollbar-thumb");
if (uct)
this._setElementTransform($sbt, "0px", -y/$v.height() * $sbt.parent().height() + "px");
setElementTransform($sbt, "0px", -y/$v.height() * $sbt.parent().height() + "px");
else
$sbt.css("top", -y/$v.height()*100 + "%");
}
@ -179,29 +191,94 @@ jQuery.widget( "mobile.scrollview", jQuery.mobile.widget, {
{
var $sbt = $hsb.find(".ui-scrollbar-thumb");
if (uct)
this._setElementTransform($sbt, -x/$v.width() * $sbt.parent().width() + "px", "0px");
setElementTransform($sbt, -x/$v.width() * $sbt.parent().width() + "px", "0px");
else
$sbt.css("left", -x/$v.width()*100 + "%");
}
}
},
scrollTo: function(x, y, duration)
{
this._stopMScroll();
if (!duration)
return this._setScrollPosition(x, y);
x = -x;
y = -y;
var self = this;
var start = getCurrentTime();
var efunc = $.easing["easeOutQuad"];
var sx = this._sx;
var sy = this._sy;
var dx = x - sx;
var dy = y - sy;
var tfunc = function(){
var elapsed = getCurrentTime() - start;
if (elapsed >= duration)
{
self._timerID = 0;
self._setScrollPosition(x, y);
}
else
{
var ec = efunc(elapsed/duration, elapsed, 0, 1, duration);
self._setScrollPosition(sx + (dx * ec), sy + (dy * ec));
self._timerID = setTimeout(tfunc, self._timerInterval);
}
};
this._timerID = setTimeout(tfunc, this._timerInterval);
},
_getScrollPosition: function(x, y)
{
return { x: this._sx, y: this._sy };
},
_handleMouseDown: function(e, ex, ey)
_getScrollHierarchy: function()
{
var svh = [];
this._$clip.parents(".ui-scrollview-clip").each(function(){
var d = $(this).data("scrollview");
if (d) svh.unshift(d);
});
return svh;
},
_getAncestorByDirection: function(dir)
{
var svh = this._getScrollHierarchy();
var n = svh.length;
while (0 < n--)
{
var sv = svh[n];
var svdir = sv.options.direction;
if (!svdir || svdir == dir)
return sv;
}
return null;
},
_handleDragStart: function(e, ex, ey)
{
// Stop any scrolling of elements in our parent hierarcy.
$.each(this._getScrollHierarchy(),function(i,sv){ sv._stopMScroll(); });
this._stopMScroll();
var c = this._$clip;
var v = this._$view;
this._lastX = ex;
this._lastY = ey;
this._doSnapBackX = false;
this._doSnapBackY = false;
this._speedX = 0;
this._speedY = 0;
this._directionLock = "";
this._didDrag = false;
if (this._hTracker)
{
@ -209,7 +286,6 @@ jQuery.widget( "mobile.scrollview", jQuery.mobile.widget, {
var vw = parseInt(v.css("width"), 10);
this._maxX = cw - vw;
if (this._maxX > 0) this._maxX = 0;
this._lastX = ex;
if (this._$hScrollBar)
this._$hScrollBar.find(".ui-scrollbar-thumb").css("width", (cw >= vw ? "100%" : Math.floor(cw/vw*100)+ "%"));
}
@ -220,7 +296,6 @@ jQuery.widget( "mobile.scrollview", jQuery.mobile.widget, {
var vh = parseInt(v.css("height"), 10);
this._maxY = ch - vh;
if (this._maxY > 0) this._maxY = 0;
this._lastY = ey;
if (this._$vScrollBar)
this._$vScrollBar.find(".ui-scrollbar-thumb").css("height", (ch >= vh ? "100%" : Math.floor(ch/vh*100)+ "%"));
}
@ -237,20 +312,69 @@ jQuery.widget( "mobile.scrollview", jQuery.mobile.widget, {
if (this.options.eventType == "mouse")
e.preventDefault();
e.stopPropagation();
},
_handleMouseMove: function(e, ex, ey)
_propagateDragMove: function(sv, e, ex, ey, dir)
{
this._hideScrollBars();
this._disableTracking();
sv._handleDragStart(e,ex,ey);
sv._directionLock = dir;
sv._didDrag = this._didDrag;
},
_handleDragMove: function(e, ex, ey)
{
this._lastMove = getCurrentTime();
var v = this._$view;
var newX = 0;
var newY = 0;
var dx = ex - this._lastX;
var dy = ey - this._lastY;
if (this._hTracker)
if (!this._directionLock)
{
var x = Math.abs(dx);
var y = Math.abs(dy);
var mt = this.options.moveThreshold;
if (x < mt && y < mt) {
return false;
}
var dir = null;
var r = 0;
if (x < y && (x/y) < 0.5) {
dir = "y";
}
else if (x > y && (y/x) < 0.5) {
dir = "x";
}
var svdir = this.options.direction;
if (svdir && dir && svdir != dir)
{
// This scrollview can't handle the direction the user
// is attempting to scroll. Find an ancestor scrollview
// that can handle the request.
var sv = this._getAncestorByDirection(dir);
if (sv)
{
this._propagateDragMove(sv, e, ex, ey, dir);
return false;
}
}
this._directionLock = svdir ? svdir : (dir ? dir : "none");
}
var newX = this._sx;
var newY = this._sy;
if (this._directionLock != "y" && this._hTracker)
{
var dx = ex - this._lastX;
var x = this._sx;
this._speedX = dx;
newX = x + dx;
@ -260,16 +384,23 @@ jQuery.widget( "mobile.scrollview", jQuery.mobile.widget, {
this._doSnapBackX = false;
if (newX > 0 || newX < this._maxX)
{
if (this._directionLock == "x")
{
var sv = this._getAncestorByDirection("x");
if (sv)
{
this._setScrollPosition(newX > 0 ? 0 : this._maxX, newY);
this._propagateDragMove(sv, e, ex, ey, dir);
return false;
}
}
newX = x + (dx/2);
this._doSnapBackX = true;
}
this._lastX = ex;
}
if (this._vTracker)
if (this._directionLock != "x" && this._vTracker)
{
var dy = ey - this._lastY;
var y = this._sy;
this._speedY = dy;
newY = y + dy;
@ -279,13 +410,27 @@ jQuery.widget( "mobile.scrollview", jQuery.mobile.widget, {
this._doSnapBackY = false;
if (newY > 0 || newY < this._maxY)
{
if (this._directionLock == "y")
{
var sv = this._getAncestorByDirection("y");
if (sv)
{
this._setScrollPosition(newX, newY > 0 ? 0 : this._maxY);
this._propagateDragMove(sv, e, ex, ey, dir);
return false;
}
}
newY = y + (dy/2);
this._doSnapBackY = true;
}
this._lastY = ey;
}
this._didDrag = true;
this._lastX = ex;
this._lastY = ey;
this._setScrollPosition(newX, newY);
this._showScrollBars();
@ -293,39 +438,44 @@ jQuery.widget( "mobile.scrollview", jQuery.mobile.widget, {
// Call preventDefault() to prevent touch devices from
// scrolling the main window.
e.preventDefault();
// e.preventDefault();
return false;
},
_handleMouseUp: function(e)
_handleDragStop: function(e)
{
var l = this._lastMove;
var t = getCurrentTime();
var doScroll = l && (t - l) <= this.options.moveThreshold;
var doScroll = l && (t - l) <= this.options.moveIntervalThreshold;
var sx = (this._hTracker && this._speedX && doScroll) ? this._speedX : (this._doSnapBackX ? 1 : 0);
var sy = (this._vTracker && this._speedY && doScroll) ? this._speedY : (this._doSnapBackY ? 1 : 0);
if (sx || sy)
{
this._startMScroll(sx, sy);
e.preventDefault();
}
else
this._hideScrollBars();
this._disableTracking();
// If a view scrolled, then we need to absorb
// the event so that links etc, underneath our
// cursor/finger don't fire.
return this._didDrag ? false : undefined;
},
_enableTracking: function()
{
$(document).bind(this._mousemoveType, this._mousemoveCB);
$(document).bind(this._mouseupType, this._mouseupCB);
$(document).bind(this._dragMoveEvt, this._dragMoveCB);
$(document).bind(this._dragStopEvt, this._dragStopCB);
},
_disableTracking: function()
{
$(document).unbind(this._mousemoveType, this._mousemoveCB);
$(document).unbind(this._mouseupType, this._mouseupCB);
$(document).unbind(this._dragMoveEvt, this._dragMoveCB);
$(document).unbind(this._dragStopEvt, this._dragStopCB);
},
_showScrollBars: function()
@ -347,36 +497,36 @@ jQuery.widget( "mobile.scrollview", jQuery.mobile.widget, {
var self = this;
if (this.options.eventType == "mouse")
{
this._mousedownType = "mousedown";
this._mousedownCB = function(e){ return self._handleMouseDown(e, e.clientX, e.clientY); };
this._dragStartEvt = "mousedown";
this._dragStartCB = function(e){ return self._handleDragStart(e, e.clientX, e.clientY); };
this._mousemoveType = "mousemove";
this._mousemoveCB = function(e){ return self._handleMouseMove(e, e.clientX, e.clientY); };
this._dragMoveEvt = "mousemove";
this._dragMoveCB = function(e){ return self._handleDragMove(e, e.clientX, e.clientY); };
this._mouseupType = "mouseup";
this._mouseupCB = function(e){ return self._handleMouseUp(e); };
this._dragStopEvt = "mouseup";
this._dragStopCB = function(e){ return self._handleDragStop(e); };
}
else // "touch"
{
this._mousedownType = "touchstart";
this._mousedownCB = function(e)
this._dragStartEvt = "touchstart";
this._dragStartCB = function(e)
{
var t = e.originalEvent.targetTouches[0];
return self._handleMouseDown(e, t.pageX, t.pageY);
return self._handleDragStart(e, t.pageX, t.pageY);
};
this._mousemoveType = "touchmove";
this._mousemoveCB = function(e)
this._dragMoveEvt = "touchmove";
this._dragMoveCB = function(e)
{
var t = e.originalEvent.targetTouches[0];
return self._handleMouseMove(e, t.pageX, t.pageY);
return self._handleDragMove(e, t.pageX, t.pageY);
};
this._mouseupType = "touchend";
this._mouseupCB = function(e){ return self._handleMouseUp(e); };
this._dragStopEvt = "touchend";
this._dragStopCB = function(e){ return self._handleDragStop(e); };
}
this._$view.bind(this._mousedownType, this._mousedownCB);
this._$view.bind(this._dragStartEvt, this._dragStartCB);
if (this.options.showScrollBars)
{
@ -385,18 +535,29 @@ jQuery.widget( "mobile.scrollview", jQuery.mobile.widget, {
var suffix = "\"><div class=\"ui-scrollbar-track\"><div class=\"ui-scrollbar-thumb\"></div></div></div>";
if (this._vTracker)
{
$c.append(prefix + "vertical" + suffix);
this._$vScrollBar = $c.children(".ui-scrollbar-vertical");
$c.append(prefix + "y" + suffix);
this._$vScrollBar = $c.children(".ui-scrollbar-y");
}
if (this._hTracker)
{
$c.append(prefix + "horizontal" + suffix);
this._$hScrollBar = $c.children(".ui-scrollbar-horizontal");
$c.append(prefix + "x" + suffix);
this._$hScrollBar = $c.children(".ui-scrollbar-x");
}
}
}
});
function setElementTransform($ele, x, y)
{
var v = "translate3d(" + x + "," + y + ", 0px)";
$ele.css({
"-moz-transform": v,
"-webkit-transform": v,
"transform": v
});
}
function MomentumTracker(options)
{
this.options = $.extend({}, options);
@ -506,7 +667,7 @@ $.extend(MomentumTracker.prototype, {
jQuery.widget( "mobile.scrolllistview", jQuery.mobile.scrollview, {
options: {
direction: "vertical"
direction: "y"
},
_create: function() {
@ -566,15 +727,10 @@ jQuery.widget( "mobile.scrolllistview", jQuery.mobile.scrollview, {
// XXX: Need to convert this over to using $().css() and supporting the non-transform case.
var ld = this._lastDivider;
if (ld && d != ld)
{
var zt = "translate3d(0px,0px,0px)";
// $(ld).css("-webkit-transform", zt).css("-moz-transform", zt).css("transform", zt);
ld.style.webkitTransform = zt; ld.style.MozTransform = zt; ld.style.transform = zt;
if (ld && d != ld) {
setElementTransform($(ld), 0, 0);
}
var str = "translate3d(0px," + y + "px,0px)";
// $(d).css("-webkit-transform", str).css("-moz-transform", str).css("transform", str);
d.style.webkitTransform = str; d.style.MozTransform = str; d.style.transform = str;
setElementTransform($(d), 0, y + "px");
this._lastDivider = d;
}

View file

@ -0,0 +1,786 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>jQuery Mobile Docs - Lists</title>
<link rel="stylesheet" href="../../themes/default" />
<link rel="stylesheet" href="jquery.mobile.scrollview.css" />
<link rel="stylesheet" href="../../docs/_assets/css/jqm-docs.css"/>
<style type="text/css">
.ui-content.ui-scrollview-clip {
padding: 0;
}
.ui-content.ui-scrollview-clip > div.ui-scrollview-view {
margin: 0;
padding: 15px;
}
.ui-content.ui-scrollview-clip > .ui-listview.ui-scrollview-view {
margin: 0;
}
.square {
width: 98px;
height: 98px;
border: solid 1px #333;
text-align: center;
line-height: 100px;
font-size: 60px;
}
.ui-scrollview-clip .ui-scrollview-clip .square {
background-color: #3CF;
}
.ui-scrollview-clip .ui-scrollview-clip .ui-scrollview-clip .square {
background-color: #F39;
}
.ui-scrollview-clip .ui-scrollview-clip .ui-scrollview-clip .ui-scrollview-clip .square {
background-color: #0F6;
}
.ui-scrollview-clip .ui-scrollview-clip .ui-scrollview-clip .ui-scrollview-clip .ui-scrollview-clip .square {
background-color: #FF6;
}
.threeByThree {
border: solid 1px black;
background-color: #999;
overflow: hidden;
width: 300px;
height: 300px;
}
.threeByThree > .ui-scrollview-view {
width: 1300px;
background-color: white;
}
.threeByThree .square {
float: left;
}
</style>
<script type="text/javascript" src="../../js"></script>
<script src="jquery.easing.1.3.js"></script>
<script src="jquery.mobile.scrollview.js"></script>
<script src="scrollview.js"></script>
<script type="text/javascript" src="../../docs/lists/docs/docs.js"></script>
</head>
<body>
<div data-role="page">
<div data-role="header">
<h1>Scroll View Direction Locking</h1>
</div><!-- /header -->
<div data-role="content">
<h4>Scrollview</h4>
<p>To turn an element into a scrollview, simply add a data-scroll="true" to the element. By default, a scrollview can scroll in both the horizontal and vertical directions. If the user drags the view horizontally (left or right), or vertically (up or down), scrolling will be locked so that it only scrolls in that one dimension. If the user drags the view diagonally, he will be able to scroll in both directions at the same time.</p>
<div data-scroll="true" class="threeByThree">
<div class="square">a</div>
<div class="square">b</div>
<div class="square">c</div>
<div class="square">d</div>
<div class="square">e</div>
<div class="square">f</div>
<div class="square">g</div>
<div class="square">h</div>
<div class="square">i</div>
<div class="square">j</div>
<div class="square">k</div>
<div class="square">l</div>
<div class="square">m</div>
<div class="square">n</div>
<div class="square">o</div>
<div class="square">p</div>
<div class="square">q</div>
<div class="square">r</div>
<div class="square">s</div>
<div class="square">t</div>
<div class="square">u</div>
<div class="square">v</div>
<div class="square">w</div>
<div class="square">x</div>
<div class="square">y</div>
<div class="square">z</div>
<div class="square">0</div>
<div class="square">1</div>
<div class="square">2</div>
<div class="square">3</div>
<div class="square">4</div>
<div class="square">5</div>
<div class="square">6</div>
<div class="square">7</div>
<div class="square">8</div>
<div class="square">9</div>
<div class="square">a</div>
<div class="square">b</div>
<div class="square">c</div>
<div class="square">d</div>
<div class="square">e</div>
<div class="square">f</div>
<div class="square">g</div>
<div class="square">h</div>
<div class="square">i</div>
<div class="square">j</div>
<div class="square">k</div>
<div class="square">l</div>
<div class="square">m</div>
<div class="square">n</div>
<div class="square">o</div>
<div class="square">p</div>
<div class="square">q</div>
<div class="square">r</div>
<div class="square">s</div>
<div class="square">t</div>
<div class="square">u</div>
<div class="square">v</div>
<div class="square">w</div>
<div class="square">x</div>
<div class="square">y</div>
<div class="square">z</div>
<div class="square">0</div>
<div class="square">1</div>
<div class="square">2</div>
<div class="square">3</div>
<div class="square">4</div>
<div class="square">5</div>
<div class="square">6</div>
<div class="square">7</div>
<div class="square">8</div>
<div class="square">9</div>
<div class="square">a</div>
<div class="square">b</div>
<div class="square">c</div>
<div class="square">d</div>
<div class="square">e</div>
<div class="square">f</div>
<div class="square">g</div>
<div class="square">h</div>
<div class="square">i</div>
<div class="square">j</div>
<div class="square">k</div>
<div class="square">l</div>
<div class="square">m</div>
<div class="square">n</div>
<div class="square">o</div>
<div class="square">p</div>
<div class="square">q</div>
<div class="square">r</div>
<div class="square">s</div>
<div class="square">t</div>
<div class="square">u</div>
<div class="square">v</div>
<div class="square">w</div>
<div class="square">x</div>
<div class="square">y</div>
<div class="square">z</div>
<div class="square">0</div>
<div class="square">1</div>
<div class="square">2</div>
<div class="square">3</div>
<div class="square">4</div>
<div class="square">5</div>
<div class="square">6</div>
<div class="square">7</div>
<div class="square">8</div>
<div class="square">9</div>
<div class="square">a</div>
<div class="square">b</div>
<div class="square">c</div>
<div class="square">d</div>
<div class="square">e</div>
<div class="square">f</div>
<div class="square">g</div>
<div class="square">h</div>
<div class="square">i</div>
<div class="square">j</div>
<div class="square">k</div>
<div class="square">l</div>
<div class="square">m</div>
<div class="square">n</div>
<div class="square">o</div>
<div class="square">p</div>
<div class="square">q</div>
<div class="square">r</div>
<div class="square">s</div>
<div class="square">t</div>
<div class="square">u</div>
<div class="square">v</div>
<div class="square">w</div>
<div class="square">x</div>
<div class="square">y</div>
<div class="square">z</div>
<div class="square">0</div>
<div class="square">1</div>
<div class="square">2</div>
<div class="square">3</div>
<div class="square">4</div>
<div class="square">5</div>
<div class="square">6</div>
<div class="square">7</div>
<div class="square">8</div>
<div class="square">9</div>
<div class="square">a</div>
<div class="square">b</div>
<div class="square">c</div>
<div class="square">d</div>
<div class="square">e</div>
<div class="square">f</div>
<div class="square">g</div>
<div class="square">h</div>
<div class="square">i</div>
<div class="square">j</div>
<div class="square">k</div>
<div class="square">l</div>
<div class="square">m</div>
<div class="square">n</div>
<div class="square">o</div>
<div class="square">p</div>
<div class="square">q</div>
<div class="square">r</div>
<div class="square">s</div>
<div class="square">t</div>
<div class="square">u</div>
<div class="square">v</div>
<div class="square">w</div>
<div class="square">x</div>
<div class="square">y</div>
</div>
<p>When there are nested scrollviews, if the user drags in a single dimension and hits either end of the view, the drag will be propagated up to the next outer scrollview that can handle a drag in that dimension. So for example, if you drag the scrollview above so that it reaches the top of its view, the entire page will start to scroll upward if you continue dragging. This is because the drag was propagated from the scrollview with the letters in it, out to the scrollview containing the entire content for the page.</p>
<h4>Horizontal Scrollview</h4>
<p>A scrollview can be set up so that it only scrolls in the horizontal direction. Simply place a data-scroll=&quot;x&quot; on the element you want to scroll:</p>
<div data-scroll="x" class="threeByThree">
<div class="square">a</div>
<div class="square">b</div>
<div class="square">c</div>
<div class="square">d</div>
<div class="square">e</div>
<div class="square">f</div>
<div class="square">g</div>
<div class="square">h</div>
<div class="square">i</div>
<div class="square">j</div>
<div class="square">k</div>
<div class="square">l</div>
<div class="square">m</div>
<div class="square">n</div>
<div class="square">o</div>
<div class="square">p</div>
<div class="square">q</div>
<div class="square">r</div>
<div class="square">s</div>
<div class="square">t</div>
<div class="square">u</div>
<div class="square">v</div>
<div class="square">w</div>
<div class="square">x</div>
<div class="square">y</div>
<div class="square">z</div>
<div class="square">0</div>
<div class="square">1</div>
<div class="square">2</div>
<div class="square">3</div>
<div class="square">4</div>
<div class="square">5</div>
<div class="square">6</div>
<div class="square">7</div>
<div class="square">8</div>
<div class="square">9</div>
<div class="square">a</div>
<div class="square">b</div>
<div class="square">c</div>
<div class="square">d</div>
<div class="square">e</div>
<div class="square">f</div>
<div class="square">g</div>
<div class="square">h</div>
<div class="square">i</div>
<div class="square">j</div>
<div class="square">k</div>
<div class="square">l</div>
<div class="square">m</div>
<div class="square">n</div>
<div class="square">o</div>
<div class="square">p</div>
<div class="square">q</div>
<div class="square">r</div>
<div class="square">s</div>
<div class="square">t</div>
<div class="square">u</div>
<div class="square">v</div>
<div class="square">w</div>
<div class="square">x</div>
<div class="square">y</div>
<div class="square">z</div>
<div class="square">0</div>
<div class="square">1</div>
<div class="square">2</div>
<div class="square">3</div>
<div class="square">4</div>
<div class="square">5</div>
<div class="square">6</div>
<div class="square">7</div>
<div class="square">8</div>
<div class="square">9</div>
<div class="square">a</div>
<div class="square">b</div>
<div class="square">c</div>
<div class="square">d</div>
<div class="square">e</div>
<div class="square">f</div>
<div class="square">g</div>
<div class="square">h</div>
<div class="square">i</div>
<div class="square">j</div>
<div class="square">k</div>
<div class="square">l</div>
<div class="square">m</div>
<div class="square">n</div>
<div class="square">o</div>
<div class="square">p</div>
<div class="square">q</div>
<div class="square">r</div>
<div class="square">s</div>
<div class="square">t</div>
<div class="square">u</div>
<div class="square">v</div>
<div class="square">w</div>
<div class="square">x</div>
<div class="square">y</div>
<div class="square">z</div>
<div class="square">0</div>
<div class="square">1</div>
<div class="square">2</div>
<div class="square">3</div>
<div class="square">4</div>
<div class="square">5</div>
<div class="square">6</div>
<div class="square">7</div>
<div class="square">8</div>
<div class="square">9</div>
<div class="square">a</div>
<div class="square">b</div>
<div class="square">c</div>
<div class="square">d</div>
<div class="square">e</div>
<div class="square">f</div>
<div class="square">g</div>
<div class="square">h</div>
<div class="square">i</div>
<div class="square">j</div>
<div class="square">k</div>
<div class="square">l</div>
<div class="square">m</div>
<div class="square">n</div>
<div class="square">o</div>
<div class="square">p</div>
<div class="square">q</div>
<div class="square">r</div>
<div class="square">s</div>
<div class="square">t</div>
<div class="square">u</div>
<div class="square">v</div>
<div class="square">w</div>
<div class="square">x</div>
<div class="square">y</div>
<div class="square">z</div>
<div class="square">0</div>
<div class="square">1</div>
<div class="square">2</div>
<div class="square">3</div>
<div class="square">4</div>
<div class="square">5</div>
<div class="square">6</div>
<div class="square">7</div>
<div class="square">8</div>
<div class="square">9</div>
<div class="square">a</div>
<div class="square">b</div>
<div class="square">c</div>
<div class="square">d</div>
<div class="square">e</div>
<div class="square">f</div>
<div class="square">g</div>
<div class="square">h</div>
<div class="square">i</div>
<div class="square">j</div>
<div class="square">k</div>
<div class="square">l</div>
<div class="square">m</div>
<div class="square">n</div>
<div class="square">o</div>
<div class="square">p</div>
<div class="square">q</div>
<div class="square">r</div>
<div class="square">s</div>
<div class="square">t</div>
<div class="square">u</div>
<div class="square">v</div>
<div class="square">w</div>
<div class="square">x</div>
<div class="square">y</div>
</div>
<h4>Vertical Scrollview</h4>
<p>A scrollview can be set up so that it only scrolls in the vertical direction. Simply place a data-scroll=&quot;y&quot; on the element you want to scroll:</p>
<div data-scroll="y" class="threeByThree">
<div class="square">a</div>
<div class="square">b</div>
<div class="square">c</div>
<div class="square">d</div>
<div class="square">e</div>
<div class="square">f</div>
<div class="square">g</div>
<div class="square">h</div>
<div class="square">i</div>
<div class="square">j</div>
<div class="square">k</div>
<div class="square">l</div>
<div class="square">m</div>
<div class="square">n</div>
<div class="square">o</div>
<div class="square">p</div>
<div class="square">q</div>
<div class="square">r</div>
<div class="square">s</div>
<div class="square">t</div>
<div class="square">u</div>
<div class="square">v</div>
<div class="square">w</div>
<div class="square">x</div>
<div class="square">y</div>
<div class="square">z</div>
<div class="square">0</div>
<div class="square">1</div>
<div class="square">2</div>
<div class="square">3</div>
<div class="square">4</div>
<div class="square">5</div>
<div class="square">6</div>
<div class="square">7</div>
<div class="square">8</div>
<div class="square">9</div>
<div class="square">a</div>
<div class="square">b</div>
<div class="square">c</div>
<div class="square">d</div>
<div class="square">e</div>
<div class="square">f</div>
<div class="square">g</div>
<div class="square">h</div>
<div class="square">i</div>
<div class="square">j</div>
<div class="square">k</div>
<div class="square">l</div>
<div class="square">m</div>
<div class="square">n</div>
<div class="square">o</div>
<div class="square">p</div>
<div class="square">q</div>
<div class="square">r</div>
<div class="square">s</div>
<div class="square">t</div>
<div class="square">u</div>
<div class="square">v</div>
<div class="square">w</div>
<div class="square">x</div>
<div class="square">y</div>
<div class="square">z</div>
<div class="square">0</div>
<div class="square">1</div>
<div class="square">2</div>
<div class="square">3</div>
<div class="square">4</div>
<div class="square">5</div>
<div class="square">6</div>
<div class="square">7</div>
<div class="square">8</div>
<div class="square">9</div>
<div class="square">a</div>
<div class="square">b</div>
<div class="square">c</div>
<div class="square">d</div>
<div class="square">e</div>
<div class="square">f</div>
<div class="square">g</div>
<div class="square">h</div>
<div class="square">i</div>
<div class="square">j</div>
<div class="square">k</div>
<div class="square">l</div>
<div class="square">m</div>
<div class="square">n</div>
<div class="square">o</div>
<div class="square">p</div>
<div class="square">q</div>
<div class="square">r</div>
<div class="square">s</div>
<div class="square">t</div>
<div class="square">u</div>
<div class="square">v</div>
<div class="square">w</div>
<div class="square">x</div>
<div class="square">y</div>
<div class="square">z</div>
<div class="square">0</div>
<div class="square">1</div>
<div class="square">2</div>
<div class="square">3</div>
<div class="square">4</div>
<div class="square">5</div>
<div class="square">6</div>
<div class="square">7</div>
<div class="square">8</div>
<div class="square">9</div>
<div class="square">a</div>
<div class="square">b</div>
<div class="square">c</div>
<div class="square">d</div>
<div class="square">e</div>
<div class="square">f</div>
<div class="square">g</div>
<div class="square">h</div>
<div class="square">i</div>
<div class="square">j</div>
<div class="square">k</div>
<div class="square">l</div>
<div class="square">m</div>
<div class="square">n</div>
<div class="square">o</div>
<div class="square">p</div>
<div class="square">q</div>
<div class="square">r</div>
<div class="square">s</div>
<div class="square">t</div>
<div class="square">u</div>
<div class="square">v</div>
<div class="square">w</div>
<div class="square">x</div>
<div class="square">y</div>
<div class="square">z</div>
<div class="square">0</div>
<div class="square">1</div>
<div class="square">2</div>
<div class="square">3</div>
<div class="square">4</div>
<div class="square">5</div>
<div class="square">6</div>
<div class="square">7</div>
<div class="square">8</div>
<div class="square">9</div>
<div class="square">a</div>
<div class="square">b</div>
<div class="square">c</div>
<div class="square">d</div>
<div class="square">e</div>
<div class="square">f</div>
<div class="square">g</div>
<div class="square">h</div>
<div class="square">i</div>
<div class="square">j</div>
<div class="square">k</div>
<div class="square">l</div>
<div class="square">m</div>
<div class="square">n</div>
<div class="square">o</div>
<div class="square">p</div>
<div class="square">q</div>
<div class="square">r</div>
<div class="square">s</div>
<div class="square">t</div>
<div class="square">u</div>
<div class="square">v</div>
<div class="square">w</div>
<div class="square">x</div>
<div class="square">y</div>
</div>
<h4>Scrollview Paging</h4>
<p>A scrollview can be set up so that it scrolls by pages. This feature is only enabled for horizontal or vertical scrollviews.</p>
<div id="ex4" data-scroll="true" class="threeByThree">
<div class="square">a</div>
<div class="square">b</div>
<div class="square">c</div>
<div class="square">d</div>
<div class="square">e</div>
<div class="square">f</div>
<div class="square">g</div>
<div class="square">h</div>
<div class="square">i</div>
<div class="square">j</div>
<div class="square">k</div>
<div class="square">l</div>
<div class="square">m</div>
<div class="square">n</div>
<div class="square">o</div>
<div class="square">p</div>
<div class="square">q</div>
<div class="square">r</div>
<div class="square">s</div>
<div class="square">t</div>
<div class="square">u</div>
<div class="square">v</div>
<div class="square">w</div>
<div class="square">x</div>
<div class="square">y</div>
<div class="square">z</div>
<div class="square">0</div>
<div class="square">1</div>
<div class="square">2</div>
<div class="square">3</div>
<div class="square">4</div>
<div class="square">5</div>
<div class="square">6</div>
<div class="square">7</div>
<div class="square">8</div>
<div class="square">9</div>
<div class="square">a</div>
<div class="square">b</div>
<div class="square">c</div>
<div class="square">d</div>
<div class="square">e</div>
<div class="square">f</div>
<div class="square">g</div>
<div class="square">h</div>
<div class="square">i</div>
<div class="square">j</div>
<div class="square">k</div>
<div class="square">l</div>
<div class="square">m</div>
<div class="square">n</div>
<div class="square">o</div>
<div class="square">p</div>
<div class="square">q</div>
<div class="square">r</div>
<div class="square">s</div>
<div class="square">t</div>
<div class="square">u</div>
<div class="square">v</div>
<div class="square">w</div>
<div class="square">x</div>
<div class="square">y</div>
<div class="square">z</div>
<div class="square">0</div>
<div class="square">1</div>
<div class="square">2</div>
<div class="square">3</div>
<div class="square">4</div>
<div class="square">5</div>
<div class="square">6</div>
<div class="square">7</div>
<div class="square">8</div>
<div class="square">9</div>
<div class="square">a</div>
<div class="square">b</div>
<div class="square">c</div>
<div class="square">d</div>
<div class="square">e</div>
<div class="square">f</div>
<div class="square">g</div>
<div class="square">h</div>
<div class="square">i</div>
<div class="square">j</div>
<div class="square">k</div>
<div class="square">l</div>
<div class="square">m</div>
<div class="square">n</div>
<div class="square">o</div>
<div class="square">p</div>
<div class="square">q</div>
<div class="square">r</div>
<div class="square">s</div>
<div class="square">t</div>
<div class="square">u</div>
<div class="square">v</div>
<div class="square">w</div>
<div class="square">x</div>
<div class="square">y</div>
<div class="square">z</div>
<div class="square">0</div>
<div class="square">1</div>
<div class="square">2</div>
<div class="square">3</div>
<div class="square">4</div>
<div class="square">5</div>
<div class="square">6</div>
<div class="square">7</div>
<div class="square">8</div>
<div class="square">9</div>
<div class="square">a</div>
<div class="square">b</div>
<div class="square">c</div>
<div class="square">d</div>
<div class="square">e</div>
<div class="square">f</div>
<div class="square">g</div>
<div class="square">h</div>
<div class="square">i</div>
<div class="square">j</div>
<div class="square">k</div>
<div class="square">l</div>
<div class="square">m</div>
<div class="square">n</div>
<div class="square">o</div>
<div class="square">p</div>
<div class="square">q</div>
<div class="square">r</div>
<div class="square">s</div>
<div class="square">t</div>
<div class="square">u</div>
<div class="square">v</div>
<div class="square">w</div>
<div class="square">x</div>
<div class="square">y</div>
<div class="square">z</div>
<div class="square">0</div>
<div class="square">1</div>
<div class="square">2</div>
<div class="square">3</div>
<div class="square">4</div>
<div class="square">5</div>
<div class="square">6</div>
<div class="square">7</div>
<div class="square">8</div>
<div class="square">9</div>
<div class="square">a</div>
<div class="square">b</div>
<div class="square">c</div>
<div class="square">d</div>
<div class="square">e</div>
<div class="square">f</div>
<div class="square">g</div>
<div class="square">h</div>
<div class="square">i</div>
<div class="square">j</div>
<div class="square">k</div>
<div class="square">l</div>
<div class="square">m</div>
<div class="square">n</div>
<div class="square">o</div>
<div class="square">p</div>
<div class="square">q</div>
<div class="square">r</div>
<div class="square">s</div>
<div class="square">t</div>
<div class="square">u</div>
<div class="square">v</div>
<div class="square">w</div>
<div class="square">x</div>
<div class="square">y</div>
</div>
<button type="button" onclick="doit();">Foo</button>
<script type="text/javascript">
function doit()
{
$("#ex4").scrollview("scrollTo", 300, 300, 500);
}
</script>
<p>Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Vestibulum tortor quam, feugiat vitae, ultricies eget, tempor sit amet, ante. Donec eu libero sit amet quam egestas semper. <em>Aenean ultricies mi vitae est.</em> Mauris placerat eleifend leo. Quisque sit amet est et sapien ullamcorper pharetra. Vestibulum erat wisi, condimentum sed, <code>commodo vitae</code>, ornare sit amet, wisi. Aenean fermentum, elit eget tincidunt condimentum, eros ipsum rutrum orci, sagittis tempus lacus enim ac dui.Donec non enim in turpis pulvinar facilisis. Ut felis.</p>
<p>Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Vestibulum tortor quam, feugiat vitae, ultricies eget, tempor sit amet, ante. Donec eu libero sit amet quam egestas semper. <em>Aenean ultricies mi vitae est.</em> Mauris placerat eleifend leo. Quisque sit amet est et sapien ullamcorper pharetra. Vestibulum erat wisi, condimentum sed, <code>commodo vitae</code>, ornare sit amet, wisi. Aenean fermentum, elit eget tincidunt condimentum, eros ipsum rutrum orci, sagittis tempus lacus enim ac dui.Donec non enim in turpis pulvinar facilisis. Ut felis.</p>
<p>Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Vestibulum tortor quam, feugiat vitae, ultricies eget, tempor sit amet, ante. Donec eu libero sit amet quam egestas semper. <em>Aenean ultricies mi vitae est.</em> Mauris placerat eleifend leo. Quisque sit amet est et sapien ullamcorper pharetra. Vestibulum erat wisi, condimentum sed, <code>commodo vitae</code>, ornare sit amet, wisi. Aenean fermentum, elit eget tincidunt condimentum, eros ipsum rutrum orci, sagittis tempus lacus enim ac dui.Donec non enim in turpis pulvinar facilisis. Ut felis.</p>
<p>&nbsp;</p>
<p></p>
</div><!-- /content -->
</div><!-- /page -->
</body>
</html>

View file

@ -0,0 +1,164 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>jQuery Mobile Docs - Lists</title>
<link rel="stylesheet" href="../../themes/default" />
<link rel="stylesheet" href="jquery.mobile.scrollview.css" />
<link rel="stylesheet" href="../../docs/_assets/css/jqm-docs.css"/>
<style type="text/css">
.ui-content.ui-scrollview-clip {
padding: 0;
}
.ui-content.ui-scrollview-clip > div.ui-scrollview-view {
margin: 0;
padding: 15px;
}
.ui-content.ui-scrollview-clip > .ui-listview.ui-scrollview-view {
margin: 0;
}
.ui-scrollview-clip {
background-color: #999;
}
.ui-scrollview-view {
background-color: white;
}
.square {
width: 200px;
height: 200px;
text-align: center;
line-height: 200px;
font-size: 160px;
}
.ui-scrollview-clip .ui-scrollview-clip .square {
background-color: #3CF;
}
.ui-scrollview-clip .ui-scrollview-clip .ui-scrollview-clip .square {
background-color: #F39;
}
.ui-scrollview-clip .ui-scrollview-clip .ui-scrollview-clip .ui-scrollview-clip .square {
background-color: #0F6;
}
.ui-scrollview-clip .ui-scrollview-clip .ui-scrollview-clip .ui-scrollview-clip .ui-scrollview-clip .square {
background-color: #FF6;
}
.single-block-view-h, .single-block-view-v {
width: 200px;
height: 200px;
}
.double-block-view-h {
border: solid 1px black;
width: 400px;
height: 200px;
}
.double-block-view-v {
border: solid 1px black;
width: 200px;
height: 400px;
}
.single-block-view-h > .view, .double-block-view-h > .view {
width: 1400px;
height: 200px;
}
.single-block-view-h > .view > .square, .double-block-view-h > .view > .square {
float: left;
}
.single-block-view-v > .view, .double-block-view-v > .view {
width: 200px;
height: 1400px;
}
</style>
<script type="text/javascript" src="../../js"></script>
<script src="jquery.easing.1.3.js"></script>
<script src="jquery.mobile.scrollview.js"></script>
<script src="scrollview.js"></script>
<script type="text/javascript" src="../../docs/lists/docs/docs.js"></script>
</head>
<body>
<div data-role="page">
<div data-role="header">
<h1>Nested Lists</h1>
</div><!-- /header -->
<div data-role="content">
<h4>Example 1</h4>
<p>In the following example the #4 is actually a vertical scrollview embedded within a horizontal scrollview.</p>
<div data-scroll="x" class="double-block-view-h">
<div class="view">
<div class="square">1</div>
<div class="square">2</div>
<div class="square">3</div>
<div data-scroll="y" class="square single-block-view-v">
<div class="view">
<div class="square">4</div>
<div class="square">A</div>
<div class="square">B</div>
<div data-scroll="x" class="single-block-view-h">
<div class="view">
<div class="square">C</div>
<div class="square">@</div>
<div class="square">#</div>
<div class="square">$</div>
<div class="square">%</div>
<div class="square">&amp;</div>
<div class="square">*</div>
</div>
</div>
<div class="square">D</div>
<div class="square">E</div>
<div class="square">F</div>
</div>
</div>
<div class="square">5</div>
<div class="square">6</div>
<div class="square">7</div>
</div>
</div>
<h4>Example 1</h4>
<p>In the following example the #4 is actually a nested horizontal scrollview embedded within a horizontal scrollview. The idea here is that if you drag-scroll the nested scrollview, once it reaches either end of its view, it should start scrolling the outer view.</p>
<div data-scroll="x" class="double-block-view-h">
<div class="view">
<div class="square">1</div>
<div class="square">2</div>
<div class="square">3</div>
<div data-scroll="x" class="square single-block-view-h">
<div class="view">
<div class="square">4</div>
<div class="square">A</div>
<div class="square">B</div>
<div class="square">C</div>
<div class="square">D</div>
<div class="square">E</div>
<div class="square">F</div>
</div>
</div>
<div class="square">5</div>
<div class="square">6</div>
<div class="square">7</div>
</div>
</div>
<p>Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Vestibulum tortor quam, feugiat vitae, ultricies eget, tempor sit amet, ante. Donec eu libero sit amet quam egestas semper. <em>Aenean ultricies mi vitae est.</em> Mauris placerat eleifend leo. Quisque sit amet est et sapien ullamcorper pharetra. Vestibulum erat wisi, condimentum sed, <code>commodo vitae</code>, ornare sit amet, wisi. Aenean fermentum, elit eget tincidunt condimentum, eros ipsum rutrum orci, sagittis tempus lacus enim ac dui.Donec non enim in turpis pulvinar facilisis. Ut felis.</p>
<p>Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Vestibulum tortor quam, feugiat vitae, ultricies eget, tempor sit amet, ante. Donec eu libero sit amet quam egestas semper. <em>Aenean ultricies mi vitae est.</em> Mauris placerat eleifend leo. Quisque sit amet est et sapien ullamcorper pharetra. Vestibulum erat wisi, condimentum sed, <code>commodo vitae</code>, ornare sit amet, wisi. Aenean fermentum, elit eget tincidunt condimentum, eros ipsum rutrum orci, sagittis tempus lacus enim ac dui.Donec non enim in turpis pulvinar facilisis. Ut felis.</p>
<p>Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Vestibulum tortor quam, feugiat vitae, ultricies eget, tempor sit amet, ante. Donec eu libero sit amet quam egestas semper. <em>Aenean ultricies mi vitae est.</em> Mauris placerat eleifend leo. Quisque sit amet est et sapien ullamcorper pharetra. Vestibulum erat wisi, condimentum sed, <code>commodo vitae</code>, ornare sit amet, wisi. Aenean fermentum, elit eget tincidunt condimentum, eros ipsum rutrum orci, sagittis tempus lacus enim ac dui.Donec non enim in turpis pulvinar facilisis. Ut felis.</p>
<p>&nbsp;</p>
<p></p>
</div><!-- /content -->
</div><!-- /page -->
</body>
</html>

View file

@ -8,12 +8,32 @@ function ResizePageContentHeight(page)
var pb = parseFloat($content.css("padding-bottom"));
var wh = window.innerHeight;
$content.height(wh - (hh + fh) - (pt + pb));
$page.children(".ui-content:not(.ui-scrollview-clip):not(.ui-scrolllistview)").scrollview({ direction: "vertical" });
$page.children(".ui-content.ui-scrolllistview:not(.ui-scrollview-clip)").scrolllistview();
}
$("[data-role=page]").live("pageshow", function(event) {
var $page = $(this);
$page.find(".ui-content, [data-scroll]").not(".ui-scrollview-clip").each(function(){
var $this = $(this);
// XXX: Remove this check for ui-scrolllistview once we've
// integrated list divider support into the main scrollview class.
if ($this.hasClass("ui-scrolllistview"))
$this.scrolllistview();
else
{
var st = $this.data("scroll") + "";
var snap = st && st.search(/^[xy]s$/ != -1);
var dir = st && st.search(/^[xy]/) != -1 ? st.charAt(0) : null;
var opts = {};
if (dir)
opts.direction = dir;
if (snap)
opts.snap = "viewport";
$this.scrollview(opts);
}
});
ResizePageContentHeight(event.target);
});