From fbaa3c12883b77e6b92ef50438c4e062a7fa58ba Mon Sep 17 00:00:00 2001 From: Kin Blas Date: Tue, 30 Nov 2010 15:20:10 -0800 Subject: [PATCH] Make sure newX and newY are initialized to the current scroll offsets. This fixes a scroll propagation bug that was resetting the non-scrolled dimension to zero. Replaced all occurences of "horizontal" and "vertical" with "x" and "y". Modified samples to use data-scroll="x|y|true". Implemented public scrollTo(0 function that gives an optional duration parameter for animated scrolling. --- .../scrollview/jquery.mobile.scrollview.css | 8 +- .../scrollview/jquery.mobile.scrollview.js | 76 +++++-- .../scrollview/scrollview-direction.html | 202 ++++++++++++++++-- experiments/scrollview/scrollview-nested.html | 29 +-- experiments/scrollview/scrollview.js | 26 ++- 5 files changed, 286 insertions(+), 55 deletions(-) diff --git a/experiments/scrollview/jquery.mobile.scrollview.css b/experiments/scrollview/jquery.mobile.scrollview.css index 098a7830..5112e431 100644 --- a/experiments/scrollview/jquery.mobile.scrollview.css +++ b/experiments/scrollview/jquery.mobile.scrollview.css @@ -24,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; @@ -54,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; } diff --git a/experiments/scrollview/jquery.mobile.scrollview.js b/experiments/scrollview/jquery.mobile.scrollview.js index a4e20106..5420c5a0 100644 --- a/experiments/scrollview/jquery.mobile.scrollview.js +++ b/experiments/scrollview/jquery.mobile.scrollview.js @@ -9,7 +9,7 @@ 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. @@ -59,8 +59,8 @@ jQuery.widget( "mobile.scrollview", jQuery.mobile.widget, { 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; @@ -160,6 +160,10 @@ jQuery.widget( "mobile.scrollview", jQuery.mobile.widget, { this._sx = x; this._sy = y; + var kdebug = 0; + if (y == 0) + ++kdebug; + var $v = this._$view; var uct = this.options.useCSSTransform; @@ -194,6 +198,40 @@ jQuery.widget( "mobile.scrollview", jQuery.mobile.widget, { } }, + 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 }; @@ -283,7 +321,7 @@ jQuery.widget( "mobile.scrollview", jQuery.mobile.widget, { this._disableTracking(); sv._handleDragStart(e,ex,ey); sv._directionLock = dir; - sv._didDrag = this.didDrag; + sv._didDrag = this._didDrag; }, _handleDragMove: function(e, ex, ey) @@ -308,10 +346,10 @@ jQuery.widget( "mobile.scrollview", jQuery.mobile.widget, { var dir = null; var r = 0; if (x < y && (x/y) < 0.5) { - dir = "vertical"; + dir = "y"; } else if (x > y && (y/x) < 0.5) { - dir = "horizontal"; + dir = "x"; } var svdir = this.options.direction; @@ -332,10 +370,10 @@ jQuery.widget( "mobile.scrollview", jQuery.mobile.widget, { this._directionLock = svdir ? svdir : (dir ? dir : "none"); } - var newX = 0; - var newY = 0; + var newX = this._sx; + var newY = this._sy; - if (this._directionLock != "vertical" && this._hTracker) + if (this._directionLock != "y" && this._hTracker) { var x = this._sx; this._speedX = dx; @@ -346,9 +384,9 @@ jQuery.widget( "mobile.scrollview", jQuery.mobile.widget, { this._doSnapBackX = false; if (newX > 0 || newX < this._maxX) { - if (this._directionLock == "horizontal") + if (this._directionLock == "x") { - var sv = this._getAncestorByDirection("horizontal"); + var sv = this._getAncestorByDirection("x"); if (sv) { this._setScrollPosition(newX > 0 ? 0 : this._maxX, newY); @@ -361,7 +399,7 @@ jQuery.widget( "mobile.scrollview", jQuery.mobile.widget, { } } - if (this._directionLock != "horizontal" && this._vTracker) + if (this._directionLock != "x" && this._vTracker) { var y = this._sy; this._speedY = dy; @@ -372,9 +410,9 @@ jQuery.widget( "mobile.scrollview", jQuery.mobile.widget, { this._doSnapBackY = false; if (newY > 0 || newY < this._maxY) { - if (this._directionLock == "vertical") + if (this._directionLock == "y") { - var sv = this._getAncestorByDirection("vertical"); + var sv = this._getAncestorByDirection("y"); if (sv) { this._setScrollPosition(newX, newY > 0 ? 0 : this._maxY); @@ -497,13 +535,13 @@ jQuery.widget( "mobile.scrollview", jQuery.mobile.widget, { var suffix = "\">
"; 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"); } } } @@ -629,7 +667,7 @@ $.extend(MomentumTracker.prototype, { jQuery.widget( "mobile.scrolllistview", jQuery.mobile.scrollview, { options: { - direction: "vertical" + direction: "y" }, _create: function() { diff --git a/experiments/scrollview/scrollview-direction.html b/experiments/scrollview/scrollview-direction.html index 499c569c..d26ed1f7 100644 --- a/experiments/scrollview/scrollview-direction.html +++ b/experiments/scrollview/scrollview-direction.html @@ -62,16 +62,6 @@ - @@ -84,7 +74,7 @@ $("[data-role=page]").live("pageshow", function(event) {

Scrollview

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.

-
+
a
b
c
@@ -257,8 +247,8 @@ $("[data-role=page]").live("pageshow", function(event) {

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.

Horizontal Scrollview

-

A scrollview can be set up so that it only scrolls in the horizontal direction. Simply place a data-scroll="horizontal" on the element you want to scroll:

-
+

A scrollview can be set up so that it only scrolls in the horizontal direction. Simply place a data-scroll="x" on the element you want to scroll:

+
a
b
c
@@ -430,8 +420,8 @@ $("[data-role=page]").live("pageshow", function(event) {
y

Vertical Scrollview

-

A scrollview can be set up so that it only scrolls in the vertical direction. Simply place a data-scroll="vertical" on the element you want to scroll:

-
+

A scrollview can be set up so that it only scrolls in the vertical direction. Simply place a data-scroll="y" on the element you want to scroll:

+
a
b
c
@@ -602,6 +592,188 @@ $("[data-role=page]").live("pageshow", function(event) {
x
y
+

Scrollview Paging

+

A scrollview can be set up so that it scrolls by pages. This feature is only enabled for horizontal or vertical scrollviews.

+
+
a
+
b
+
c
+
d
+
e
+
f
+
g
+
h
+
i
+
j
+
k
+
l
+
m
+
n
+
o
+
p
+
q
+
r
+
s
+
t
+
u
+
v
+
w
+
x
+
y
+
z
+
0
+
1
+
2
+
3
+
4
+
5
+
6
+
7
+
8
+
9
+
a
+
b
+
c
+
d
+
e
+
f
+
g
+
h
+
i
+
j
+
k
+
l
+
m
+
n
+
o
+
p
+
q
+
r
+
s
+
t
+
u
+
v
+
w
+
x
+
y
+
z
+
0
+
1
+
2
+
3
+
4
+
5
+
6
+
7
+
8
+
9
+
a
+
b
+
c
+
d
+
e
+
f
+
g
+
h
+
i
+
j
+
k
+
l
+
m
+
n
+
o
+
p
+
q
+
r
+
s
+
t
+
u
+
v
+
w
+
x
+
y
+
z
+
0
+
1
+
2
+
3
+
4
+
5
+
6
+
7
+
8
+
9
+
a
+
b
+
c
+
d
+
e
+
f
+
g
+
h
+
i
+
j
+
k
+
l
+
m
+
n
+
o
+
p
+
q
+
r
+
s
+
t
+
u
+
v
+
w
+
x
+
y
+
z
+
0
+
1
+
2
+
3
+
4
+
5
+
6
+
7
+
8
+
9
+
a
+
b
+
c
+
d
+
e
+
f
+
g
+
h
+
i
+
j
+
k
+
l
+
m
+
n
+
o
+
p
+
q
+
r
+
s
+
t
+
u
+
v
+
w
+
x
+
y
+
+ +

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. Aenean ultricies mi vitae est. Mauris placerat eleifend leo. Quisque sit amet est et sapien ullamcorper pharetra. Vestibulum erat wisi, condimentum sed, commodo vitae, 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.

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. Aenean ultricies mi vitae est. Mauris placerat eleifend leo. Quisque sit amet est et sapien ullamcorper pharetra. Vestibulum erat wisi, condimentum sed, commodo vitae, 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.

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. Aenean ultricies mi vitae est. Mauris placerat eleifend leo. Quisque sit amet est et sapien ullamcorper pharetra. Vestibulum erat wisi, condimentum sed, commodo vitae, 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.

diff --git a/experiments/scrollview/scrollview-nested.html b/experiments/scrollview/scrollview-nested.html index dbee1d09..d3cea894 100644 --- a/experiments/scrollview/scrollview-nested.html +++ b/experiments/scrollview/scrollview-nested.html @@ -86,15 +86,6 @@ - @@ -107,17 +98,27 @@ $("[data-role=page]").live("pageshow", function(event) {

Example 1

In the following example the #4 is actually a vertical scrollview embedded within a horizontal scrollview.

-
+
1
2
3
-
+
4
A
B
-
C
+
+
+
C
+
@
+
#
+
$
+
%
+
&
+
*
+
+
D
E
F
@@ -130,12 +131,12 @@ $("[data-role=page]").live("pageshow", function(event) {

Example 1

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.

-
+
1
2
3
-
+
4
A
diff --git a/experiments/scrollview/scrollview.js b/experiments/scrollview/scrollview.js index 83cf790b..b3b97016 100644 --- a/experiments/scrollview/scrollview.js +++ b/experiments/scrollview/scrollview.js @@ -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); });