Commit | Line | Data |
---|---|---|
784ae106 D |
1 | /*!\r |
2 | * iScroll v4.1.4 ~ Copyright (c) 2011 Matteo Spinelli, http://cubiq.org\r | |
3 | * Released under MIT license, http://cubiq.org/license\r | |
4 | */\r | |
5 | \r | |
6 | (function(){\r | |
7 | var m = Math,\r | |
8 | vendor = (/webkit/i).test(navigator.appVersion) ? 'webkit' :\r | |
9 | (/firefox/i).test(navigator.userAgent) ? 'Moz' :\r | |
10 | 'opera' in window ? 'O' : '',\r | |
11 | \r | |
12 | // Browser capabilities\r | |
13 | has3d = 'WebKitCSSMatrix' in window && 'm11' in new WebKitCSSMatrix(),\r | |
14 | hasTouch = 'ontouchstart' in window,\r | |
15 | hasTransform = vendor + 'Transform' in document.documentElement.style,\r | |
16 | isAndroid = (/android/gi).test(navigator.appVersion),\r | |
17 | isIDevice = (/iphone|ipad/gi).test(navigator.appVersion),\r | |
18 | isPlaybook = (/playbook/gi).test(navigator.appVersion),\r | |
19 | hasTransitionEnd = (isIDevice || isPlaybook) && 'onwebkittransitionend' in window,\r | |
20 | nextFrame = (function() {\r | |
21 | return window.requestAnimationFrame\r | |
22 | || window.webkitRequestAnimationFrame\r | |
23 | || window.mozRequestAnimationFrame\r | |
24 | || window.oRequestAnimationFrame\r | |
25 | || window.msRequestAnimationFrame\r | |
26 | || function(callback) { return setTimeout(callback, 17); }\r | |
27 | })(),\r | |
28 | cancelFrame = (function () {\r | |
29 | return window.cancelRequestAnimationFrame\r | |
30 | || window.webkitCancelRequestAnimationFrame\r | |
31 | || window.mozCancelRequestAnimationFrame\r | |
32 | || window.oCancelRequestAnimationFrame\r | |
33 | || window.msCancelRequestAnimationFrame\r | |
34 | || clearTimeout\r | |
35 | })(),\r | |
36 | \r | |
37 | // Events\r | |
38 | RESIZE_EV = 'onorientationchange' in window ? 'orientationchange' : 'resize',\r | |
39 | START_EV = hasTouch ? 'touchstart' : 'mousedown',\r | |
40 | MOVE_EV = hasTouch ? 'touchmove' : 'mousemove',\r | |
41 | END_EV = hasTouch ? 'touchend' : 'mouseup',\r | |
42 | CANCEL_EV = hasTouch ? 'touchcancel' : 'mouseup',\r | |
43 | WHEEL_EV = vendor == 'Moz' ? 'DOMMouseScroll' : 'mousewheel',\r | |
44 | \r | |
45 | // Helpers\r | |
46 | trnOpen = 'translate' + (has3d ? '3d(' : '('),\r | |
47 | trnClose = has3d ? ',0)' : ')',\r | |
48 | \r | |
49 | // Constructor\r | |
50 | iScroll = function (el, options) {\r | |
51 | var that = this,\r | |
52 | doc = document,\r | |
53 | i;\r | |
54 | \r | |
55 | that.wrapper = typeof el == 'object' ? el : doc.getElementById(el);\r | |
56 | that.wrapper.style.overflow = 'hidden';\r | |
57 | that.scroller = that.wrapper.children[0];\r | |
58 | \r | |
59 | // Default options\r | |
60 | that.options = {\r | |
61 | hScroll: true,\r | |
62 | vScroll: true,\r | |
63 | bounce: true,\r | |
64 | bounceLock: false,\r | |
65 | momentum: true,\r | |
66 | lockDirection: true,\r | |
67 | useTransform: true,\r | |
68 | useTransition: false,\r | |
69 | \r | |
70 | // Scrollbar\r | |
71 | hScrollbar: true,\r | |
72 | vScrollbar: true,\r | |
73 | fixedScrollbar: isAndroid,\r | |
74 | hideScrollbar: isIDevice,\r | |
75 | fadeScrollbar: isIDevice && has3d,\r | |
76 | scrollbarClass: '',\r | |
77 | \r | |
78 | // Zoom\r | |
79 | zoom: false,\r | |
80 | zoomMin: 1,\r | |
81 | zoomMax: 4,\r | |
82 | doubleTapZoom: 2,\r | |
83 | \r | |
84 | // Snap\r | |
85 | snap: false,\r | |
86 | snapThreshold: 1,\r | |
87 | \r | |
88 | // Events\r | |
89 | onRefresh: null,\r | |
90 | onBeforeScrollStart: function (e) { e.preventDefault(); },\r | |
91 | onScrollStart: null,\r | |
92 | onBeforeScrollMove: null,\r | |
93 | onScrollMove: null,\r | |
94 | onBeforeScrollEnd: null,\r | |
95 | onScrollEnd: null,\r | |
96 | onTouchEnd: null,\r | |
97 | onDestroy: null\r | |
98 | };\r | |
99 | \r | |
100 | // User defined options\r | |
101 | for (i in options) that.options[i] = options[i];\r | |
102 | \r | |
103 | // Normalize options\r | |
104 | that.options.useTransform = hasTransform ? that.options.useTransform : false;\r | |
105 | that.options.hScrollbar = that.options.hScroll && that.options.hScrollbar;\r | |
106 | that.options.vScrollbar = that.options.vScroll && that.options.vScrollbar;\r | |
107 | that.options.zoom = that.options.useTransform && that.options.zoom;\r | |
108 | that.options.useTransition = hasTransitionEnd && that.options.useTransition;\r | |
109 | \r | |
110 | // Set some default styles\r | |
111 | that.scroller.style[vendor + 'TransitionProperty'] = that.options.useTransform ? '-' + vendor.toLowerCase() + '-transform' : 'top left';\r | |
112 | that.scroller.style[vendor + 'TransitionDuration'] = '0';\r | |
113 | that.scroller.style[vendor + 'TransformOrigin'] = '0 0';\r | |
114 | if (that.options.useTransition) that.scroller.style[vendor + 'TransitionTimingFunction'] = 'cubic-bezier(0.33,0.66,0.66,1)';\r | |
115 | \r | |
116 | if (that.options.useTransform) that.scroller.style[vendor + 'Transform'] = trnOpen + '0,0' + trnClose;\r | |
117 | else that.scroller.style.cssText += ';top:0;left:0';\r | |
118 | \r | |
119 | if (that.options.useTransition) that.options.fixedScrollbar = true;\r | |
120 | \r | |
121 | that.refresh();\r | |
122 | \r | |
123 | that._bind(RESIZE_EV, window);\r | |
124 | that._bind(START_EV);\r | |
125 | if (!hasTouch) {\r | |
126 | that._bind('mouseout', that.wrapper);\r | |
127 | that._bind(WHEEL_EV);\r | |
128 | }\r | |
129 | };\r | |
130 | \r | |
131 | // Prototype\r | |
132 | iScroll.prototype = {\r | |
133 | enabled: true,\r | |
134 | x: 0,\r | |
135 | y: 0,\r | |
136 | steps: [],\r | |
137 | scale: 1,\r | |
138 | currPageX: 0, currPageY: 0,\r | |
139 | pagesX: [], pagesY: [],\r | |
140 | aniTime: null,\r | |
141 | \r | |
142 | handleEvent: function (e) {\r | |
143 | var that = this;\r | |
144 | switch(e.type) {\r | |
145 | case START_EV: that._start(e); break;\r | |
146 | case MOVE_EV: that._move(e); break;\r | |
147 | case END_EV:\r | |
148 | case CANCEL_EV: that._end(e); break;\r | |
149 | case RESIZE_EV: that._resize(); break;\r | |
150 | case WHEEL_EV: that._wheel(e); break;\r | |
151 | case 'mouseout': that._mouseout(e); break;\r | |
152 | case 'webkitTransitionEnd': that._transitionEnd(e); break;\r | |
153 | }\r | |
154 | },\r | |
155 | \r | |
156 | _scrollbar: function (dir) {\r | |
157 | var that = this,\r | |
158 | doc = document,\r | |
159 | bar;\r | |
160 | \r | |
161 | if (!that[dir + 'Scrollbar']) {\r | |
162 | if (that[dir + 'ScrollbarWrapper']) {\r | |
163 | if (hasTransform) that[dir + 'ScrollbarIndicator'].style[vendor + 'Transform'] = '';\r | |
164 | that[dir + 'ScrollbarWrapper'].parentNode.removeChild(that[dir + 'ScrollbarWrapper']);\r | |
165 | that[dir + 'ScrollbarWrapper'] = null;\r | |
166 | that[dir + 'ScrollbarIndicator'] = null;\r | |
167 | }\r | |
168 | \r | |
169 | return;\r | |
170 | }\r | |
171 | \r | |
172 | if (!that[dir + 'ScrollbarWrapper']) {\r | |
173 | // Create the scrollbar wrapper\r | |
174 | bar = doc.createElement('div');\r | |
175 | \r | |
176 | if (that.options.scrollbarClass) bar.className = that.options.scrollbarClass + dir.toUpperCase();\r | |
177 | else bar.style.cssText = 'position:absolute;z-index:100;' + (dir == 'h' ? 'height:7px;bottom:1px;left:2px;right:' + (that.vScrollbar ? '7' : '2') + 'px' : 'width:7px;bottom:' + (that.hScrollbar ? '7' : '2') + 'px;top:2px;right:1px');\r | |
178 | \r | |
179 | bar.style.cssText += ';pointer-events:none;-' + vendor + '-transition-property:opacity;-' + vendor + '-transition-duration:' + (that.options.fadeScrollbar ? '350ms' : '0') + ';overflow:hidden;opacity:' + (that.options.hideScrollbar ? '0' : '1');\r | |
180 | \r | |
181 | that.wrapper.appendChild(bar);\r | |
182 | that[dir + 'ScrollbarWrapper'] = bar;\r | |
183 | \r | |
184 | // Create the scrollbar indicator\r | |
185 | bar = doc.createElement('div');\r | |
186 | if (!that.options.scrollbarClass) {\r | |
187 | bar.style.cssText = 'position:absolute;z-index:100;background:rgba(0,0,0,0.5);border:1px solid rgba(255,255,255,0.9);-' + vendor + '-background-clip:padding-box;-' + vendor + '-box-sizing:border-box;' + (dir == 'h' ? 'height:100%' : 'width:100%') + ';-' + vendor + '-border-radius:3px;border-radius:3px';\r | |
188 | }\r | |
189 | bar.style.cssText += ';pointer-events:none;-' + vendor + '-transition-property:-' + vendor + '-transform;-' + vendor + '-transition-timing-function:cubic-bezier(0.33,0.66,0.66,1);-' + vendor + '-transition-duration:0;-' + vendor + '-transform:' + trnOpen + '0,0' + trnClose;\r | |
190 | if (that.options.useTransition) bar.style.cssText += ';-' + vendor + '-transition-timing-function:cubic-bezier(0.33,0.66,0.66,1)';\r | |
191 | \r | |
192 | that[dir + 'ScrollbarWrapper'].appendChild(bar);\r | |
193 | that[dir + 'ScrollbarIndicator'] = bar;\r | |
194 | }\r | |
195 | \r | |
196 | if (dir == 'h') {\r | |
197 | that.hScrollbarSize = that.hScrollbarWrapper.clientWidth;\r | |
198 | that.hScrollbarIndicatorSize = m.max(m.round(that.hScrollbarSize * that.hScrollbarSize / that.scrollerW), 8);\r | |
199 | that.hScrollbarIndicator.style.width = that.hScrollbarIndicatorSize + 'px';\r | |
200 | that.hScrollbarMaxScroll = that.hScrollbarSize - that.hScrollbarIndicatorSize;\r | |
201 | that.hScrollbarProp = that.hScrollbarMaxScroll / that.maxScrollX;\r | |
202 | } else {\r | |
203 | that.vScrollbarSize = that.vScrollbarWrapper.clientHeight;\r | |
204 | that.vScrollbarIndicatorSize = m.max(m.round(that.vScrollbarSize * that.vScrollbarSize / that.scrollerH), 8);\r | |
205 | that.vScrollbarIndicator.style.height = that.vScrollbarIndicatorSize + 'px';\r | |
206 | that.vScrollbarMaxScroll = that.vScrollbarSize - that.vScrollbarIndicatorSize;\r | |
207 | that.vScrollbarProp = that.vScrollbarMaxScroll / that.maxScrollY;\r | |
208 | }\r | |
209 | \r | |
210 | // Reset position\r | |
211 | that._scrollbarPos(dir, true);\r | |
212 | },\r | |
213 | \r | |
214 | _resize: function () {\r | |
215 | this.refresh();\r | |
216 | },\r | |
217 | \r | |
218 | _pos: function (x, y) {\r | |
219 | x = this.hScroll ? x : 0;\r | |
220 | y = this.vScroll ? y : 0;\r | |
221 | \r | |
222 | if (this.options.useTransform) {\r | |
223 | this.scroller.style[vendor + 'Transform'] = trnOpen + x + 'px,' + y + 'px' + trnClose + ' scale(' + this.scale + ')';\r | |
224 | } else {\r | |
225 | x = m.round(x);\r | |
226 | y = m.round(y);\r | |
227 | this.scroller.style.left = x + 'px';\r | |
228 | this.scroller.style.top = y + 'px';\r | |
229 | }\r | |
230 | \r | |
231 | this.x = x;\r | |
232 | this.y = y;\r | |
233 | \r | |
234 | this._scrollbarPos('h');\r | |
235 | this._scrollbarPos('v');\r | |
236 | },\r | |
237 | \r | |
238 | _scrollbarPos: function (dir, hidden) {\r | |
239 | var that = this,\r | |
240 | pos = dir == 'h' ? that.x : that.y,\r | |
241 | size;\r | |
242 | \r | |
243 | if (!that[dir + 'Scrollbar']) return;\r | |
244 | \r | |
245 | pos = that[dir + 'ScrollbarProp'] * pos;\r | |
246 | \r | |
247 | if (pos < 0) {\r | |
248 | if (!that.options.fixedScrollbar) {\r | |
249 | size = that[dir + 'ScrollbarIndicatorSize'] + m.round(pos * 3);\r | |
250 | if (size < 8) size = 8;\r | |
251 | that[dir + 'ScrollbarIndicator'].style[dir == 'h' ? 'width' : 'height'] = size + 'px';\r | |
252 | }\r | |
253 | pos = 0;\r | |
254 | } else if (pos > that[dir + 'ScrollbarMaxScroll']) {\r | |
255 | if (!that.options.fixedScrollbar) {\r | |
256 | size = that[dir + 'ScrollbarIndicatorSize'] - m.round((pos - that[dir + 'ScrollbarMaxScroll']) * 3);\r | |
257 | if (size < 8) size = 8;\r | |
258 | that[dir + 'ScrollbarIndicator'].style[dir == 'h' ? 'width' : 'height'] = size + 'px';\r | |
259 | pos = that[dir + 'ScrollbarMaxScroll'] + (that[dir + 'ScrollbarIndicatorSize'] - size);\r | |
260 | } else {\r | |
261 | pos = that[dir + 'ScrollbarMaxScroll'];\r | |
262 | }\r | |
263 | }\r | |
264 | \r | |
265 | that[dir + 'ScrollbarWrapper'].style[vendor + 'TransitionDelay'] = '0';\r | |
266 | that[dir + 'ScrollbarWrapper'].style.opacity = hidden && that.options.hideScrollbar ? '0' : '1';\r | |
267 | that[dir + 'ScrollbarIndicator'].style[vendor + 'Transform'] = trnOpen + (dir == 'h' ? pos + 'px,0' : '0,' + pos + 'px') + trnClose;\r | |
268 | },\r | |
269 | \r | |
270 | _start: function (e) {\r | |
271 | var that = this,\r | |
272 | point = hasTouch ? e.touches[0] : e,\r | |
273 | matrix, x, y,\r | |
274 | c1, c2, target;\r | |
275 | \r | |
276 | if (!that.enabled) return;\r | |
277 | \r | |
278 | if (that.options.onBeforeScrollStart) that.options.onBeforeScrollStart.call(that, e);\r | |
279 | \r | |
280 | if (that.options.useTransition) that._transitionTime(0);\r | |
281 | \r | |
282 | that.moved = false;\r | |
283 | that.animating = false;\r | |
284 | that.zoomed = false;\r | |
285 | that.distX = 0;\r | |
286 | that.distY = 0;\r | |
287 | that.absDistX = 0;\r | |
288 | that.absDistY = 0;\r | |
289 | that.dirX = 0;\r | |
290 | that.dirY = 0;\r | |
291 | \r | |
292 | // Gesture start\r | |
293 | if (that.options.zoom && hasTouch && e.touches.length > 1) {\r | |
294 | c1 = m.abs(e.touches[0].pageX-e.touches[1].pageX);\r | |
295 | c2 = m.abs(e.touches[0].pageY-e.touches[1].pageY);\r | |
296 | that.touchesDistStart = m.sqrt(c1 * c1 + c2 * c2);\r | |
297 | \r | |
298 | that.originX = m.abs(e.touches[0].pageX + e.touches[1].pageX - that.wrapperOffsetLeft * 2) / 2 - that.x;\r | |
299 | that.originY = m.abs(e.touches[0].pageY + e.touches[1].pageY - that.wrapperOffsetTop * 2) / 2 - that.y;\r | |
300 | }\r | |
301 | \r | |
302 | if (that.options.momentum) {\r | |
303 | if (that.options.useTransform) {\r | |
304 | // Very lame general purpose alternative to CSSMatrix\r | |
305 | matrix = getComputedStyle(that.scroller, null)[vendor + 'Transform'].replace(/[^0-9-.,]/g, '').split(',');\r | |
306 | x = matrix[4] * 1;\r | |
307 | y = matrix[5] * 1;\r | |
308 | } else {\r | |
309 | x = getComputedStyle(that.scroller, null).left.replace(/[^0-9-]/g, '') * 1;\r | |
310 | y = getComputedStyle(that.scroller, null).top.replace(/[^0-9-]/g, '') * 1;\r | |
311 | }\r | |
312 | \r | |
313 | if (x != that.x || y != that.y) {\r | |
314 | if (that.options.useTransition) that._unbind('webkitTransitionEnd');\r | |
315 | else cancelFrame(that.aniTime);\r | |
316 | that.steps = [];\r | |
317 | that._pos(x, y);\r | |
318 | }\r | |
319 | }\r | |
320 | \r | |
321 | that.absStartX = that.x; // Needed by snap threshold\r | |
322 | that.absStartY = that.y;\r | |
323 | \r | |
324 | that.startX = that.x;\r | |
325 | that.startY = that.y;\r | |
326 | that.pointX = point.pageX;\r | |
327 | that.pointY = point.pageY;\r | |
328 | \r | |
329 | that.startTime = e.timeStamp || (new Date()).getTime();\r | |
330 | \r | |
331 | if (that.options.onScrollStart) that.options.onScrollStart.call(that, e);\r | |
332 | \r | |
333 | that._bind(MOVE_EV);\r | |
334 | that._bind(END_EV);\r | |
335 | that._bind(CANCEL_EV);\r | |
336 | },\r | |
337 | \r | |
338 | _move: function (e) {\r | |
339 | var that = this,\r | |
340 | point = hasTouch ? e.touches[0] : e,\r | |
341 | deltaX = point.pageX - that.pointX,\r | |
342 | deltaY = point.pageY - that.pointY,\r | |
343 | newX = that.x + deltaX,\r | |
344 | newY = that.y + deltaY,\r | |
345 | c1, c2, scale,\r | |
346 | timestamp = e.timeStamp || (new Date()).getTime();\r | |
347 | \r | |
348 | if (that.options.onBeforeScrollMove) that.options.onBeforeScrollMove.call(that, e);\r | |
349 | \r | |
350 | // Zoom\r | |
351 | if (that.options.zoom && hasTouch && e.touches.length > 1) {\r | |
352 | c1 = m.abs(e.touches[0].pageX - e.touches[1].pageX);\r | |
353 | c2 = m.abs(e.touches[0].pageY - e.touches[1].pageY);\r | |
354 | that.touchesDist = m.sqrt(c1*c1+c2*c2);\r | |
355 | \r | |
356 | that.zoomed = true;\r | |
357 | \r | |
358 | scale = 1 / that.touchesDistStart * that.touchesDist * this.scale;\r | |
359 | if (scale < 0.5) scale = 0.5;\r | |
360 | else if (scale > that.options.zoomMax) scale = that.options.zoomMax;\r | |
361 | that.lastScale = scale / this.scale;\r | |
362 | \r | |
363 | newX = this.originX - this.originX * that.lastScale + this.x,\r | |
364 | newY = this.originY - this.originY * that.lastScale + this.y;\r | |
365 | \r | |
366 | this.scroller.style[vendor + 'Transform'] = trnOpen + newX + 'px,' + newY + 'px' + trnClose + ' scale(' + scale + ')';\r | |
367 | \r | |
368 | return;\r | |
369 | }\r | |
370 | \r | |
371 | that.pointX = point.pageX;\r | |
372 | that.pointY = point.pageY;\r | |
373 | \r | |
374 | // Slow down if outside of the boundaries\r | |
375 | if (newX > 0 || newX < that.maxScrollX) {\r | |
376 | newX = that.options.bounce ? that.x + (deltaX / 2) : newX >= 0 || that.maxScrollX >= 0 ? 0 : that.maxScrollX;\r | |
377 | }\r | |
378 | if (newY > 0 || newY < that.maxScrollY) { \r | |
379 | newY = that.options.bounce ? that.y + (deltaY / 2) : newY >= 0 || that.maxScrollY >= 0 ? 0 : that.maxScrollY;\r | |
380 | }\r | |
381 | \r | |
382 | if (that.absDistX < 6 && that.absDistY < 6) {\r | |
383 | that.distX += deltaX;\r | |
384 | that.distY += deltaY;\r | |
385 | that.absDistX = m.abs(that.distX);\r | |
386 | that.absDistY = m.abs(that.distY);\r | |
387 | \r | |
388 | return;\r | |
389 | }\r | |
390 | \r | |
391 | // Lock direction\r | |
392 | if (that.options.lockDirection) {\r | |
393 | if (that.absDistX > that.absDistY + 5) {\r | |
394 | newY = that.y;\r | |
395 | deltaY = 0;\r | |
396 | } else if (that.absDistY > that.absDistX + 5) {\r | |
397 | newX = that.x;\r | |
398 | deltaX = 0;\r | |
399 | }\r | |
400 | }\r | |
401 | \r | |
402 | that.moved = true;\r | |
403 | that._pos(newX, newY);\r | |
404 | that.dirX = deltaX > 0 ? -1 : deltaX < 0 ? 1 : 0;\r | |
405 | that.dirY = deltaY > 0 ? -1 : deltaY < 0 ? 1 : 0;\r | |
406 | \r | |
407 | if (timestamp - that.startTime > 300) {\r | |
408 | that.startTime = timestamp;\r | |
409 | that.startX = that.x;\r | |
410 | that.startY = that.y;\r | |
411 | }\r | |
412 | \r | |
413 | if (that.options.onScrollMove) that.options.onScrollMove.call(that, e);\r | |
414 | },\r | |
415 | \r | |
416 | _end: function (e) {\r | |
417 | if (hasTouch && e.touches.length != 0) return;\r | |
418 | \r | |
419 | var that = this,\r | |
420 | point = hasTouch ? e.changedTouches[0] : e,\r | |
421 | target, ev,\r | |
422 | momentumX = { dist:0, time:0 },\r | |
423 | momentumY = { dist:0, time:0 },\r | |
424 | duration = (e.timeStamp || (new Date()).getTime()) - that.startTime,\r | |
425 | newPosX = that.x,\r | |
426 | newPosY = that.y,\r | |
427 | distX, distY,\r | |
428 | newDuration;\r | |
429 | \r | |
430 | that._unbind(MOVE_EV);\r | |
431 | that._unbind(END_EV);\r | |
432 | that._unbind(CANCEL_EV);\r | |
433 | \r | |
434 | if (that.options.onBeforeScrollEnd) that.options.onBeforeScrollEnd.call(that, e);\r | |
435 | \r | |
436 | if (that.zoomed) {\r | |
437 | that.scale = that.scale * that.lastScale;\r | |
438 | that.x = that.originX - that.originX * that.lastScale + that.x;\r | |
439 | that.y = that.originY - that.originY * that.lastScale + that.y;\r | |
440 | \r | |
441 | that.scroller.style.webkitTransform = trnOpen + that.x + 'px,' + that.y + 'px' + trnClose + ' scale(' + that.scale + ')';\r | |
442 | \r | |
443 | that.refresh();\r | |
444 | return;\r | |
445 | }\r | |
446 | \r | |
447 | if (!that.moved) {\r | |
448 | if (hasTouch) {\r | |
449 | if (that.doubleTapTimer && that.options.zoom) {\r | |
450 | // Double tapped\r | |
451 | clearTimeout(that.doubleTapTimer);\r | |
452 | that.doubleTapTimer = null;\r | |
453 | that.zoom(that.pointX, that.pointY, that.scale == 1 ? that.options.doubleTapZoom : 1);\r | |
454 | } else {\r | |
455 | that.doubleTapTimer = setTimeout(function () {\r | |
456 | that.doubleTapTimer = null;\r | |
457 | \r | |
458 | // Find the last touched element\r | |
459 | target = point.target;\r | |
460 | while (target.nodeType != 1) target = target.parentNode;\r | |
461 | \r | |
462 | if (target.tagName != 'SELECT' && target.tagName != 'INPUT' && target.tagName != 'TEXTAREA') {\r | |
463 | ev = document.createEvent('MouseEvents');\r | |
464 | ev.initMouseEvent('click', true, true, e.view, 1,\r | |
465 | point.screenX, point.screenY, point.clientX, point.clientY,\r | |
466 | e.ctrlKey, e.altKey, e.shiftKey, e.metaKey,\r | |
467 | 0, null);\r | |
468 | ev._fake = true;\r | |
469 | target.dispatchEvent(ev);\r | |
470 | }\r | |
471 | }, that.options.zoom ? 250 : 0);\r | |
472 | }\r | |
473 | }\r | |
474 | \r | |
475 | that._resetPos(200);\r | |
476 | \r | |
477 | if (that.options.onTouchEnd) that.options.onTouchEnd.call(that, e);\r | |
478 | return;\r | |
479 | }\r | |
480 | \r | |
481 | if (duration < 300 && that.options.momentum) {\r | |
482 | momentumX = newPosX ? that._momentum(newPosX - that.startX, duration, -that.x, that.scrollerW - that.wrapperW + that.x, that.options.bounce ? that.wrapperW : 0) : momentumX;\r | |
483 | momentumY = newPosY ? that._momentum(newPosY - that.startY, duration, -that.y, (that.maxScrollY < 0 ? that.scrollerH - that.wrapperH + that.y : 0), that.options.bounce ? that.wrapperH : 0) : momentumY;\r | |
484 | \r | |
485 | newPosX = that.x + momentumX.dist;\r | |
486 | newPosY = that.y + momentumY.dist;\r | |
487 | \r | |
488 | if ((that.x > 0 && newPosX > 0) || (that.x < that.maxScrollX && newPosX < that.maxScrollX)) momentumX = { dist:0, time:0 };\r | |
489 | if ((that.y > 0 && newPosY > 0) || (that.y < that.maxScrollY && newPosY < that.maxScrollY)) momentumY = { dist:0, time:0 };\r | |
490 | }\r | |
491 | \r | |
492 | if (momentumX.dist || momentumY.dist) {\r | |
493 | newDuration = m.max(m.max(momentumX.time, momentumY.time), 10);\r | |
494 | \r | |
495 | // Do we need to snap?\r | |
496 | if (that.options.snap) {\r | |
497 | distX = newPosX - that.absStartX;\r | |
498 | distY = newPosY - that.absStartY;\r | |
499 | if (m.abs(distX) < that.options.snapThreshold && m.abs(distY) < that.options.snapThreshold) { that.scrollTo(that.absStartX, that.absStartY, 200); }\r | |
500 | else {\r | |
501 | snap = that._snap(newPosX, newPosY);\r | |
502 | newPosX = snap.x;\r | |
503 | newPosY = snap.y;\r | |
504 | newDuration = m.max(snap.time, newDuration);\r | |
505 | }\r | |
506 | }\r | |
507 | \r | |
508 | that.scrollTo(newPosX, newPosY, newDuration);\r | |
509 | \r | |
510 | if (that.options.onTouchEnd) that.options.onTouchEnd.call(that, e);\r | |
511 | return;\r | |
512 | }\r | |
513 | \r | |
514 | // Do we need to snap?\r | |
515 | if (that.options.snap) {\r | |
516 | distX = newPosX - that.absStartX;\r | |
517 | distY = newPosY - that.absStartY;\r | |
518 | if (m.abs(distX) < that.options.snapThreshold && m.abs(distY) < that.options.snapThreshold) that.scrollTo(that.absStartX, that.absStartY, 200);\r | |
519 | else {\r | |
520 | snap = that._snap(that.x, that.y);\r | |
521 | if (snap.x != that.x || snap.y != that.y) that.scrollTo(snap.x, snap.y, snap.time);\r | |
522 | }\r | |
523 | \r | |
524 | if (that.options.onTouchEnd) that.options.onTouchEnd.call(that, e);\r | |
525 | return;\r | |
526 | }\r | |
527 | \r | |
528 | that._resetPos(200);\r | |
529 | if (that.options.onTouchEnd) that.options.onTouchEnd.call(that, e);\r | |
530 | },\r | |
531 | \r | |
532 | _resetPos: function (time) {\r | |
533 | var that = this,\r | |
534 | resetX = that.x >= 0 ? 0 : that.x < that.maxScrollX ? that.maxScrollX : that.x,\r | |
535 | resetY = that.y >= 0 || that.maxScrollY > 0 ? 0 : that.y < that.maxScrollY ? that.maxScrollY : that.y;\r | |
536 | \r | |
537 | if (resetX == that.x && resetY == that.y) {\r | |
538 | if (that.moved) {\r | |
539 | that.moved = false;\r | |
540 | if (that.options.onScrollEnd) that.options.onScrollEnd.call(that); // Execute custom code on scroll end\r | |
541 | }\r | |
542 | \r | |
543 | if (that.hScrollbar && that.options.hideScrollbar) {\r | |
544 | if (vendor == 'webkit') that.hScrollbarWrapper.style[vendor + 'TransitionDelay'] = '300ms';\r | |
545 | that.hScrollbarWrapper.style.opacity = '0';\r | |
546 | }\r | |
547 | if (that.vScrollbar && that.options.hideScrollbar) {\r | |
548 | if (vendor == 'webkit') that.vScrollbarWrapper.style[vendor + 'TransitionDelay'] = '300ms';\r | |
549 | that.vScrollbarWrapper.style.opacity = '0';\r | |
550 | }\r | |
551 | \r | |
552 | return;\r | |
553 | }\r | |
554 | \r | |
555 | that.scrollTo(resetX, resetY, time || 0);\r | |
556 | },\r | |
557 | \r | |
558 | _wheel: function (e) {\r | |
559 | var that = this,\r | |
560 | deltaX, deltaY;\r | |
561 | \r | |
562 | if ('wheelDeltaX' in e) {\r | |
563 | deltaX = that.x + e.wheelDeltaX / 12,\r | |
564 | deltaY = that.y + e.wheelDeltaY / 12;\r | |
565 | } else if ('detail' in e) {\r | |
566 | deltaX = that.x - e.detail * 3,\r | |
567 | deltaY = that.y - e.detail * 3;\r | |
568 | } else {\r | |
569 | deltaX = that.x - e.wheelDelta,\r | |
570 | deltaY = that.y - e.wheelDelta;\r | |
571 | }\r | |
572 | \r | |
573 | if (deltaX > 0) deltaX = 0;\r | |
574 | else if (deltaX < that.maxScrollX) deltaX = that.maxScrollX;\r | |
575 | \r | |
576 | if (deltaY > 0) deltaY = 0;\r | |
577 | else if (deltaY < that.maxScrollY) deltaY = that.maxScrollY;\r | |
578 | \r | |
579 | that.scrollTo(deltaX, deltaY, 0);\r | |
580 | },\r | |
581 | \r | |
582 | _mouseout: function (e) {\r | |
583 | var t = e.relatedTarget;\r | |
584 | \r | |
585 | if (!t) {\r | |
586 | this._end(e);\r | |
587 | return;\r | |
588 | }\r | |
589 | \r | |
590 | while (t = t.parentNode) if (t == this.wrapper) return;\r | |
591 | \r | |
592 | this._end(e);\r | |
593 | },\r | |
594 | \r | |
595 | _transitionEnd: function (e) {\r | |
596 | var that = this;\r | |
597 | \r | |
598 | if (e.target != that.scroller) return;\r | |
599 | \r | |
600 | that._unbind('webkitTransitionEnd');\r | |
601 | \r | |
602 | that._startAni();\r | |
603 | },\r | |
604 | \r | |
605 | \r | |
606 | /**\r | |
607 | *\r | |
608 | * Utilities\r | |
609 | *\r | |
610 | */\r | |
611 | _startAni: function () {\r | |
612 | var that = this,\r | |
613 | startX = that.x, startY = that.y,\r | |
614 | startTime = (new Date).getTime(),\r | |
615 | step, easeOut;\r | |
616 | \r | |
617 | if (that.animating) return;\r | |
618 | \r | |
619 | if (!that.steps.length) {\r | |
620 | that._resetPos(400);\r | |
621 | return;\r | |
622 | }\r | |
623 | \r | |
624 | step = that.steps.shift();\r | |
625 | \r | |
626 | if (step.x == startX && step.y == startY) step.time = 0;\r | |
627 | \r | |
628 | that.animating = true;\r | |
629 | that.moved = true;\r | |
630 | \r | |
631 | if (that.options.useTransition) {\r | |
632 | that._transitionTime(step.time);\r | |
633 | that._pos(step.x, step.y);\r | |
634 | that.animating = false;\r | |
635 | if (step.time) that._bind('webkitTransitionEnd');\r | |
636 | return;\r | |
637 | }\r | |
638 | \r | |
639 | (function animate () {\r | |
640 | var now = (new Date).getTime(),\r | |
641 | newX, newY;\r | |
642 | \r | |
643 | if (now >= startTime + step.time) {\r | |
644 | that._pos(step.x, step.y);\r | |
645 | that.animating = false;\r | |
646 | if (that.options.onAnimationEnd) that.options.onAnimationEnd.call(that); // Execute custom code on animation end\r | |
647 | that._startAni();\r | |
648 | return;\r | |
649 | }\r | |
650 | \r | |
651 | now = (now - startTime) / step.time - 1;\r | |
652 | easeOut = m.sqrt(1 - now * now);\r | |
653 | newX = (step.x - startX) * easeOut + startX;\r | |
654 | newY = (step.y - startY) * easeOut + startY;\r | |
655 | that._pos(newX, newY);\r | |
656 | if (that.animating) that.aniTime = nextFrame(animate);\r | |
657 | })();\r | |
658 | },\r | |
659 | \r | |
660 | _transitionTime: function (time) {\r | |
661 | time += 'ms';\r | |
662 | this.scroller.style[vendor + 'TransitionDuration'] = time;\r | |
663 | if (this.hScrollbar) this.hScrollbarIndicator.style[vendor + 'TransitionDuration'] = time;\r | |
664 | if (this.vScrollbar) this.vScrollbarIndicator.style[vendor + 'TransitionDuration'] = time;\r | |
665 | },\r | |
666 | \r | |
667 | _momentum: function (dist, time, maxDistUpper, maxDistLower, size) {\r | |
668 | var deceleration = 0.0006,\r | |
669 | speed = m.abs(dist) / time,\r | |
670 | newDist = (speed * speed) / (2 * deceleration),\r | |
671 | newTime = 0, outsideDist = 0;\r | |
672 | \r | |
673 | // Proportinally reduce speed if we are outside of the boundaries \r | |
674 | if (dist > 0 && newDist > maxDistUpper) {\r | |
675 | outsideDist = size / (6 / (newDist / speed * deceleration));\r | |
676 | maxDistUpper = maxDistUpper + outsideDist;\r | |
677 | speed = speed * maxDistUpper / newDist;\r | |
678 | newDist = maxDistUpper;\r | |
679 | } else if (dist < 0 && newDist > maxDistLower) {\r | |
680 | outsideDist = size / (6 / (newDist / speed * deceleration));\r | |
681 | maxDistLower = maxDistLower + outsideDist;\r | |
682 | speed = speed * maxDistLower / newDist;\r | |
683 | newDist = maxDistLower;\r | |
684 | }\r | |
685 | \r | |
686 | newDist = newDist * (dist < 0 ? -1 : 1);\r | |
687 | newTime = speed / deceleration;\r | |
688 | \r | |
689 | return { dist: newDist, time: m.round(newTime) };\r | |
690 | },\r | |
691 | \r | |
692 | _offset: function (el) {\r | |
693 | var left = -el.offsetLeft,\r | |
694 | top = -el.offsetTop;\r | |
695 | \r | |
696 | while (el = el.offsetParent) {\r | |
697 | left -= el.offsetLeft;\r | |
698 | top -= el.offsetTop;\r | |
699 | }\r | |
700 | \r | |
701 | if (el != this.wrapper) {\r | |
702 | left *= this.scale;\r | |
703 | top *= this.scale;\r | |
704 | }\r | |
705 | \r | |
706 | return { left: left, top: top };\r | |
707 | },\r | |
708 | \r | |
709 | _snap: function (x, y) {\r | |
710 | var that = this,\r | |
711 | i, l,\r | |
712 | page, time,\r | |
713 | sizeX, sizeY;\r | |
714 | \r | |
715 | // Check page X\r | |
716 | page = that.pagesX.length - 1;\r | |
717 | for (i=0, l=that.pagesX.length; i<l; i++) {\r | |
718 | if (x >= that.pagesX[i]) {\r | |
719 | page = i;\r | |
720 | break;\r | |
721 | }\r | |
722 | }\r | |
723 | if (page == that.currPageX && page > 0 && that.dirX < 0) page--;\r | |
724 | x = that.pagesX[page];\r | |
725 | sizeX = m.abs(x - that.pagesX[that.currPageX]);\r | |
726 | sizeX = sizeX ? m.abs(that.x - x) / sizeX * 500 : 0;\r | |
727 | that.currPageX = page;\r | |
728 | \r | |
729 | // Check page Y\r | |
730 | page = that.pagesY.length-1;\r | |
731 | for (i=0; i<page; i++) {\r | |
732 | if (y >= that.pagesY[i]) {\r | |
733 | page = i;\r | |
734 | break;\r | |
735 | }\r | |
736 | }\r | |
737 | if (page == that.currPageY && page > 0 && that.dirY < 0) page--;\r | |
738 | y = that.pagesY[page];\r | |
739 | sizeY = m.abs(y - that.pagesY[that.currPageY]);\r | |
740 | sizeY = sizeY ? m.abs(that.y - y) / sizeY * 500 : 0;\r | |
741 | that.currPageY = page;\r | |
742 | \r | |
743 | // Snap with constant speed (proportional duration)\r | |
744 | time = m.round(m.max(sizeX, sizeY)) || 200;\r | |
745 | \r | |
746 | return { x: x, y: y, time: time };\r | |
747 | },\r | |
748 | \r | |
749 | _bind: function (type, el, bubble) {\r | |
750 | (el || this.scroller).addEventListener(type, this, !!bubble);\r | |
751 | },\r | |
752 | \r | |
753 | _unbind: function (type, el, bubble) {\r | |
754 | (el || this.scroller).removeEventListener(type, this, !!bubble);\r | |
755 | },\r | |
756 | \r | |
757 | \r | |
758 | /**\r | |
759 | *\r | |
760 | * Public methods\r | |
761 | *\r | |
762 | */\r | |
763 | destroy: function () {\r | |
764 | var that = this;\r | |
765 | \r | |
766 | that.scroller.style[vendor + 'Transform'] = '';\r | |
767 | \r | |
768 | // Remove the scrollbars\r | |
769 | that.hScrollbar = false;\r | |
770 | that.vScrollbar = false;\r | |
771 | that._scrollbar('h');\r | |
772 | that._scrollbar('v');\r | |
773 | \r | |
774 | // Remove the event listeners\r | |
775 | that._unbind(RESIZE_EV);\r | |
776 | that._unbind(START_EV);\r | |
777 | that._unbind(MOVE_EV);\r | |
778 | that._unbind(END_EV);\r | |
779 | that._unbind(CANCEL_EV);\r | |
780 | \r | |
781 | if (that.options.hasTouch) {\r | |
782 | that._unbind('mouseout', that.wrapper);\r | |
783 | that._unbind(WHEEL_EV);\r | |
784 | }\r | |
785 | \r | |
786 | if (that.options.useTransition) that._unbind('webkitTransitionEnd');\r | |
787 | \r | |
788 | if (that.options.onDestroy) that.options.onDestroy.call(that);\r | |
789 | },\r | |
790 | \r | |
791 | refresh: function () {\r | |
792 | var that = this,\r | |
793 | offset,\r | |
794 | pos = 0,\r | |
795 | page = 0;\r | |
796 | \r | |
797 | if (that.scale < that.options.zoomMin) that.scale = that.options.zoomMin;\r | |
798 | that.wrapperW = that.wrapper.clientWidth || 1;\r | |
799 | that.wrapperH = that.wrapper.clientHeight || 1;\r | |
800 | \r | |
801 | that.scrollerW = m.round(that.scroller.offsetWidth * that.scale);\r | |
802 | that.scrollerH = m.round(that.scroller.offsetHeight * that.scale);\r | |
803 | that.maxScrollX = that.wrapperW - that.scrollerW;\r | |
804 | that.maxScrollY = that.wrapperH - that.scrollerH;\r | |
805 | that.dirX = 0;\r | |
806 | that.dirY = 0;\r | |
807 | \r | |
808 | that.hScroll = that.options.hScroll && that.maxScrollX < 0;\r | |
809 | that.vScroll = that.options.vScroll && (!that.options.bounceLock && !that.hScroll || that.scrollerH > that.wrapperH);\r | |
810 | \r | |
811 | that.hScrollbar = that.hScroll && that.options.hScrollbar;\r | |
812 | that.vScrollbar = that.vScroll && that.options.vScrollbar && that.scrollerH > that.wrapperH;\r | |
813 | \r | |
814 | offset = that._offset(that.wrapper);\r | |
815 | that.wrapperOffsetLeft = -offset.left;\r | |
816 | that.wrapperOffsetTop = -offset.top;\r | |
817 | \r | |
818 | // Prepare snap\r | |
819 | if (typeof that.options.snap == 'string') {\r | |
820 | that.pagesX = [];\r | |
821 | that.pagesY = [];\r | |
822 | els = that.scroller.querySelectorAll(that.options.snap);\r | |
823 | for (i=0, l=els.length; i<l; i++) {\r | |
824 | pos = that._offset(els[i]);\r | |
825 | pos.left += that.wrapperOffsetLeft;\r | |
826 | pos.top += that.wrapperOffsetTop;\r | |
827 | that.pagesX[i] = pos.left < that.maxScrollX ? that.maxScrollX : pos.left * that.scale;\r | |
828 | that.pagesY[i] = pos.top < that.maxScrollY ? that.maxScrollY : pos.top * that.scale;\r | |
829 | }\r | |
830 | } else if (that.options.snap) {\r | |
831 | that.pagesX = [];\r | |
832 | while (pos >= that.maxScrollX) {\r | |
833 | that.pagesX[page] = pos;\r | |
834 | pos = pos - that.wrapperW;\r | |
835 | page++;\r | |
836 | }\r | |
837 | if (that.maxScrollX%that.wrapperW) that.pagesX[that.pagesX.length] = that.maxScrollX - that.pagesX[that.pagesX.length-1] + that.pagesX[that.pagesX.length-1];\r | |
838 | \r | |
839 | pos = 0;\r | |
840 | page = 0;\r | |
841 | that.pagesY = [];\r | |
842 | while (pos >= that.maxScrollY) {\r | |
843 | that.pagesY[page] = pos;\r | |
844 | pos = pos - that.wrapperH;\r | |
845 | page++;\r | |
846 | }\r | |
847 | if (that.maxScrollY%that.wrapperH) that.pagesY[that.pagesY.length] = that.maxScrollY - that.pagesY[that.pagesY.length-1] + that.pagesY[that.pagesY.length-1];\r | |
848 | }\r | |
849 | \r | |
850 | // Prepare the scrollbars\r | |
851 | that._scrollbar('h');\r | |
852 | that._scrollbar('v');\r | |
853 | \r | |
854 | that.scroller.style[vendor + 'TransitionDuration'] = '0';\r | |
855 | \r | |
856 | that._resetPos(200);\r | |
857 | },\r | |
858 | \r | |
859 | scrollTo: function (x, y, time, relative) {\r | |
860 | var that = this,\r | |
861 | step = x,\r | |
862 | i, l;\r | |
863 | \r | |
864 | that.stop();\r | |
865 | \r | |
866 | if (!step.length) step = [{ x: x, y: y, time: time, relative: relative }];\r | |
867 | \r | |
868 | for (i=0, l=step.length; i<l; i++) {\r | |
869 | if (step[i].relative) { step[i].x = that.x - step[i].x; step[i].y = that.y - step[i].y; }\r | |
870 | that.steps.push({ x: step[i].x, y: step[i].y, time: step[i].time || 0 });\r | |
871 | }\r | |
872 | \r | |
873 | that._startAni();\r | |
874 | },\r | |
875 | \r | |
876 | scrollToElement: function (el, time) {\r | |
877 | var that = this, pos;\r | |
878 | el = el.nodeType ? el : that.scroller.querySelector(el);\r | |
879 | if (!el) return;\r | |
880 | \r | |
881 | pos = that._offset(el);\r | |
882 | pos.left += that.wrapperOffsetLeft;\r | |
883 | pos.top += that.wrapperOffsetTop;\r | |
884 | \r | |
885 | pos.left = pos.left > 0 ? 0 : pos.left < that.maxScrollX ? that.maxScrollX : pos.left;\r | |
886 | pos.top = pos.top > 0 ? 0 : pos.top < that.maxScrollY ? that.maxScrollY : pos.top;\r | |
887 | time = time === undefined ? m.max(m.abs(pos.left)*2, m.abs(pos.top)*2) : time;\r | |
888 | \r | |
889 | that.scrollTo(pos.left, pos.top, time);\r | |
890 | },\r | |
891 | \r | |
892 | scrollToPage: function (pageX, pageY, time) {\r | |
893 | var that = this, x, y;\r | |
894 | \r | |
895 | if (that.options.snap) {\r | |
896 | pageX = pageX == 'next' ? that.currPageX+1 : pageX == 'prev' ? that.currPageX-1 : pageX;\r | |
897 | pageY = pageY == 'next' ? that.currPageY+1 : pageY == 'prev' ? that.currPageY-1 : pageY;\r | |
898 | \r | |
899 | pageX = pageX < 0 ? 0 : pageX > that.pagesX.length-1 ? that.pagesX.length-1 : pageX;\r | |
900 | pageY = pageY < 0 ? 0 : pageY > that.pagesY.length-1 ? that.pagesY.length-1 : pageY;\r | |
901 | \r | |
902 | that.currPageX = pageX;\r | |
903 | that.currPageY = pageY;\r | |
904 | x = that.pagesX[pageX];\r | |
905 | y = that.pagesY[pageY];\r | |
906 | } else {\r | |
907 | x = -that.wrapperW * pageX;\r | |
908 | y = -that.wrapperH * pageY;\r | |
909 | if (x < that.maxScrollX) x = that.maxScrollX;\r | |
910 | if (y < that.maxScrollY) y = that.maxScrollY;\r | |
911 | }\r | |
912 | \r | |
913 | that.scrollTo(x, y, time || 400);\r | |
914 | },\r | |
915 | \r | |
916 | disable: function () {\r | |
917 | this.stop();\r | |
918 | this._resetPos(0);\r | |
919 | this.enabled = false;\r | |
920 | \r | |
921 | // If disabled after touchstart we make sure that there are no left over events\r | |
922 | this._unbind(MOVE_EV);\r | |
923 | this._unbind(END_EV);\r | |
924 | this._unbind(CANCEL_EV);\r | |
925 | },\r | |
926 | \r | |
927 | enable: function () {\r | |
928 | this.enabled = true;\r | |
929 | },\r | |
930 | \r | |
931 | stop: function () {\r | |
932 | if (this.options.useTransition) this._unbind('webkitTransitionEnd');\r | |
933 | else cancelFrame(this.aniTime);\r | |
934 | this.steps = [];\r | |
935 | this.moved = false;\r | |
936 | this.animating = false;\r | |
937 | },\r | |
938 | \r | |
939 | zoom: function (x, y, scale, time) {\r | |
940 | var that = this,\r | |
941 | relScale = scale / that.scale;\r | |
942 | \r | |
943 | if (!that.options.useTransform) return;\r | |
944 | \r | |
945 | time = (time || 200) + 'ms'\r | |
946 | x = x - that.wrapperOffsetLeft - that.x;\r | |
947 | y = y - that.wrapperOffsetTop - that.y;\r | |
948 | that.x = x - x * relScale + that.x;\r | |
949 | that.y = y - y * relScale + that.y;\r | |
950 | \r | |
951 | that.scale = scale;\r | |
952 | \r | |
953 | that.scroller.style[vendor + 'TransitionDuration'] = time;\r | |
954 | that.scroller.style[vendor + 'Transform'] = trnOpen + that.x + 'px,' + that.y + 'px' + trnClose + ' scale(' + scale + ')';\r | |
955 | \r | |
956 | that.refresh();\r | |
957 | }\r | |
958 | };\r | |
959 | \r | |
960 | if (typeof exports !== 'undefined') exports.iScroll = iScroll;\r | |
961 | else window.iScroll = iScroll;\r | |
962 | \r | |
963 | })(); |