The response has been limited to 50k tokens of the smallest files in the repo. You can remove this limitation by removing the max tokens filter.
├── .gitignore
├── .nodemonignore
├── CONTRIBUTING.md
├── LICENSE
├── README.md
├── RELEASENOTES.md
├── bower.json
├── build.js
├── build
    ├── iscroll-infinite.js
    ├── iscroll-lite.js
    ├── iscroll-probe.js
    ├── iscroll-zoom.js
    └── iscroll.js
├── demos
    ├── 2d-scroll
    │   └── index.html
    ├── barebone
    │   └── index.html
    ├── bounce-easing
    │   └── index.html
    ├── carousel
    │   ├── gaugin.jpg
    │   ├── giotto.jpg
    │   ├── index.html
    │   ├── leonardo.jpg
    │   └── warhol.jpg
    ├── click
    │   └── index.html
    ├── demoUtils.js
    ├── event-passthrough
    │   └── index.html
    ├── forms
    │   └── index.html
    ├── horizontal
    │   └── index.html
    ├── infinite
    │   ├── dataset.php
    │   └── index.html
    ├── key-bindings
    │   └── index.html
    ├── minimap
    │   ├── ermine.jpg
    │   └── index.html
    ├── no-transition
    │   └── index.html
    ├── parallax
    │   ├── galaxies1.png
    │   ├── galaxies2.png
    │   ├── index.html
    │   └── stars.jpg
    ├── probe
    │   └── index.html
    ├── scroll-to-element
    │   └── index.html
    ├── scrollbars
    │   └── index.html
    ├── simple
    │   └── index.html
    ├── snap
    │   └── index.html
    ├── styled-scrollbars
    │   └── index.html
    ├── tap
    │   └── index.html
    └── zoom
    │   └── index.html
├── package.json
└── src
    ├── close.js
    ├── core.js
    ├── default
        ├── _animate.js
        └── handleEvent.js
    ├── indicator
        ├── _initIndicators.js
        ├── _transitionTime.js
        ├── _transitionTimingFunction.js
        ├── _translate.js
        ├── build.json
        └── indicator.js
    ├── infinite
        ├── build.json
        ├── infinite.js
        └── refresh.js
    ├── keys
        ├── build.json
        └── keys.js
    ├── open.js
    ├── probe
        ├── _animate.js
        ├── _move.js
        ├── build.json
        ├── indicator._move.js
        └── probe.js
    ├── snap
        ├── _end.js
        ├── build.json
        ├── refresh.js
        └── snap.js
    ├── utils.js
    ├── wheel
        ├── build.json
        └── wheel.js
    └── zoom
        ├── build.json
        ├── handleEvent.js
        ├── refresh.js
        └── zoom.js


/.gitignore:
--------------------------------------------------------------------------------
1 | .DS_Store
2 | ._*
3 | node_modules
4 | dist


--------------------------------------------------------------------------------
/.nodemonignore:
--------------------------------------------------------------------------------
1 | /build/*
2 | /dist/*
3 | /demos/*
4 | *.md
5 | *.tmp


--------------------------------------------------------------------------------
/CONTRIBUTING.md:
--------------------------------------------------------------------------------
1 | # Contributing to iScroll / FAQ
2 | 
3 | You are very welcome to collaborate, all changes to the code will be released under an MIT license.
4 | 
5 | By submitting a pull request you implicitly agree to give rights of your code to the project authors. Your contribution will always be released under the same MIT license.
6 | 


--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
 1 | Copyright (c) 2008-2013 Matteo Spinelli, http://cubiq.org
 2 | 
 3 | Permission is hereby granted, free of charge, to any person
 4 | obtaining a copy of this software and associated documentation
 5 | files (the "Software"), to deal in the Software without
 6 | restriction, including without limitation the rights to use,
 7 | copy, modify, merge, publish, distribute, sublicense, and/or sell
 8 | copies of the Software, and to permit persons to whom the
 9 | Software is furnished to do so, subject to the following
10 | conditions:
11 | 
12 | The above copyright notice and this permission notice shall be
13 | included in all copies or substantial portions of the Software.
14 | 
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
17 | OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
19 | HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
20 | WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21 | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
22 | OTHER DEALINGS IN THE SOFTWARE.


--------------------------------------------------------------------------------
/RELEASENOTES.md:
--------------------------------------------------------------------------------
 1 | # Release notes for iScroll
 2 | 
 3 | ---
 4 | 
 5 | ##  Version 5.2.0 - 2016.04.05
 6 | 
 7 | ### Fixes
 8 | * Fixes weird scrolling in Chrome (#760, #441, #943, #927, #780)
 9 | * [#1009](https://github.com/cubiq/iscroll/issues/1009) fixes utils.prefixPointerEvent method
10 | * [#1018](https://github.com/cubiq/iscroll/issues/1018), [#652](https://github.com/cubiq/iscroll/issues/652) fixes directionX/Y when scrolling with mouse
11 | * [#924](https://github.com/cubiq/iscroll/issues/924), [#950](https://github.com/cubiq/iscroll/issues/950) clean up timer on destroy
12 | * [#949](https://github.com/cubiq/iscroll/issues/949) removes unnecesary style values on wrapper when useTransition option is 'false'
13 | * [#361](https://github.com/cubiq/iscroll/issues/361) fixes two click/tap events issue
14 | * [#980](https://github.com/cubiq/iscroll/issues/980) fixes event propagation for wheel event
15 | * [#768](https://github.com/cubiq/iscroll/issues/768) fixes indicators
16 | * [#761](https://github.com/cubiq/iscroll/issues/761) fixes two scrollEnd events issue
17 | * Fixes 'click' event is not fired when iScroll is disabled
18 | 
19 | ### Changes
20 | * Added AMD support
21 | * Changed default value of disableMouse/disableTouch/disablePointer options
22 | * Removed CLA non-sense
23 | 
24 | ---
25 | 
26 | ##  Version 5.1.3 - 2014.09.19
27 | 
28 | ### Fixes
29 | * [#577](https://github.com/cubiq/iscroll/issues/577) fixes scrolling in Firefox
30 | 
31 | ---
32 | 
33 | ##  Version 5.1.2 - 2014.06.02
34 | 
35 | ### Fixes
36 | * [#707](https://github.com/cubiq/iscroll/pull/707) fixes build fail when dist folder does not exist
37 | * [#713](https://github.com/cubiq/iscroll/pull/713) Adds W3C pointer support and fixes issue with `MSPointerEvent` detection
38 | 
39 | ---
40 | 
41 | ##  Version 5.1.1 - 2014.01.10
42 | 
43 | ### Fixes
44 | * Infinite scroll now switch from `transform` to `top/left` based on `useTransform` option
45 | * [#555](https://github.com/cubiq/iscroll/issues/555) removed unused variable
46 | * [#372](https://github.com/cubiq/iscroll/issues/372) case insensitive check on tag names
47 | 
48 | ### New features
49 | * New `off` method to unload custom events
50 | * Added `options.deceleration` to alter the momentum duration/speed
51 | * Added release notes file
52 | 
53 | ---
54 | 
55 | ##  Version 5.1.0 - 2014.01.09
56 | 
57 | ### Fixes
58 | * [#558](https://github.com/cubiq/iscroll/issues/558) false positive for `isBadAndroid`
59 | 
60 | ### New features
61 | * Infinite scrolling
62 | * Documentation
63 | * `_execEvent` supports arguments
64 | 
65 | ### Changes
66 | * dist/minified files are no longer pushed to the main repo
67 | 
68 | ---
69 | 
70 | *I started collecting release notes from version 5.1.0*
71 | 


--------------------------------------------------------------------------------
/bower.json:
--------------------------------------------------------------------------------
 1 | {
 2 |   "name": "iscroll",
 3 |   "description": "Smooth scrolling for the web",
 4 |   "main": [
 5 |     "build/iscroll.js"
 6 |   ],
 7 |   "moduleType": [
 8 |     "amd",
 9 |     "node",
10 |     "globals"
11 |   ],
12 |   "keywords": [
13 |     "scrolling",
14 |     "carousel",
15 |     "zoom",
16 |     "iphone",
17 |     "android",
18 |     "mobile",
19 |     "desktop"
20 |   ],
21 |   "authors": [
22 |     "Matteo Spinelli <matteo@cubiq.org> (http://cubiq.org)"
23 |   ],
24 |   "license": "MIT",
25 |   "repository": {
26 |     "type": "git",
27 |     "url": "https://github.com/cubiq/iscroll.git"
28 |   },
29 |   "homepage": "http://iscrolljs.com",
30 |   "ignore": [
31 |     "**/.*",
32 |     "build/*",
33 |     "dist/*",
34 |     "demos/*",
35 |     "*.md",
36 |     "*.tmp",
37 |     "build.js",
38 |     "package.json"
39 |   ]
40 | }
41 | 


--------------------------------------------------------------------------------
/build.js:
--------------------------------------------------------------------------------
  1 | #!/usr/bin/env node
  2 | 
  3 | var pkg = require('./package.json');
  4 | var fs = require('fs');
  5 | var hint = require("jshint").JSHINT;
  6 | var uglify = require('uglify-js');
  7 | 
  8 | var banner = '/*! iScroll v' + pkg.version + ' ~ (c) 2008-' + (new Date().getFullYear()) + ' Matteo Spinelli ~ http://cubiq.org/license */\n';
  9 | 
 10 | var releases = {
 11 | 	lite: {
 12 | 		files: [
 13 | 			'default/_animate.js',
 14 | 			'default/handleEvent.js'
 15 | 		]
 16 | 	},
 17 | 
 18 | 	iscroll: {
 19 | 		files: [
 20 | 			'indicator/_initIndicators.js',
 21 | 			'wheel/wheel.js',
 22 | 			'snap/snap.js',
 23 | 			'keys/keys.js',
 24 | 			'default/_animate.js',
 25 | 			'default/handleEvent.js',
 26 | 			'indicator/indicator.js'
 27 | 		],
 28 | 		postProcessing: [ 'indicator/build.json', 'wheel/build.json', 'snap/build.json', 'keys/build.json' ]
 29 | 	},
 30 | 
 31 | 	probe: {
 32 | 		files: [
 33 | 			'indicator/_initIndicators.js',
 34 | 			'wheel/wheel.js',
 35 | 			'snap/snap.js',
 36 | 			'keys/keys.js',
 37 | 			'probe/_animate.js',
 38 | 			'default/handleEvent.js',
 39 | 			'indicator/indicator.js'
 40 | 		],
 41 | 		postProcessing: [ 'indicator/build.json', 'wheel/build.json', 'snap/build.json', 'keys/build.json', 'probe/build.json' ]
 42 | 	},
 43 | 
 44 | 	zoom: {
 45 | 		files: [
 46 | 			'indicator/_initIndicators.js',
 47 | 			'zoom/zoom.js',
 48 | 			'wheel/wheel.js',
 49 | 			'snap/snap.js',
 50 | 			'keys/keys.js',
 51 | 			'default/_animate.js',
 52 | 			'zoom/handleEvent.js',
 53 | 			'indicator/indicator.js'
 54 | 		],
 55 | 		postProcessing: [ 'zoom/build.json', 'indicator/build.json', 'wheel/build.json', 'snap/build.json', 'keys/build.json' ]
 56 | 	},
 57 | 
 58 | 	infinite: {
 59 | 		files: [
 60 | 			'wheel/wheel.js',
 61 | 			'snap/snap.js',
 62 | 			'keys/keys.js',
 63 | 			'probe/_animate.js',
 64 | 			'infinite/infinite.js',
 65 | 			'default/handleEvent.js',
 66 | 		],
 67 | 		postProcessing: [ 'wheel/build.json', 'snap/build.json', 'keys/build.json', 'infinite/build.json', 'probe/build.json' ]
 68 | 	}
 69 | };
 70 | 
 71 | var args = process.argv.slice(2);
 72 | 
 73 | if ( !args.length ) {
 74 | 	args = ['iscroll'];
 75 | }
 76 | 
 77 | if ( args[0] == 'dist' ) {
 78 | 	args = ['lite', 'iscroll', 'zoom', 'probe', 'infinite'];
 79 | }
 80 | 
 81 | // Get the list of files
 82 | args.forEach(function (release) {
 83 | 	if ( !(release in releases) ) {
 84 | 		console.log('Unrecognized release: ' + release);
 85 | 		return;
 86 | 	}
 87 | 
 88 | 	console.log('Building release: ' + release);
 89 | 	build(release);
 90 | });
 91 | 
 92 | function build (release) {
 93 | 	var out = '';
 94 | 	var value = '';
 95 | 
 96 | 	var fileList = ['open.js', 'utils.js', 'core.js'];
 97 | 
 98 | 	fileList = fileList.concat(releases[release].files);
 99 | 
100 | 	fileList.push('close.js');
101 | 
102 | 	// Concatenate files
103 | 	out = banner + fileList.map(function (filePath) {
104 | 				return fs.readFileSync('src/' + filePath, 'utf-8');
105 | 			}).join('');
106 | 
107 | 	// Update version
108 | 	out = out.replace('/* VERSION */', pkg.version);
109 | 
110 | 	// Post processing
111 | 	if ( releases[release].postProcessing ) {
112 | 		releases[release].postProcessing.forEach(function (file) {
113 | 			var postProcessing = require('./src/' + file);
114 | 
115 | 			// Insert point
116 | 			for ( var i in postProcessing.insert ) {
117 | 				value = postProcessing.insert[i].substr(postProcessing.insert[i].length-3) == '.js' ? 
118 | 					fs.readFileSync('src/' + postProcessing.insert[i]) :
119 | 					postProcessing.insert[i];
120 | 
121 | 				out = out.replace('// INSERT POINT: ' + i, value + '\n\n// INSERT POINT: ' + i );
122 | 			}
123 | 
124 | 			// Replace
125 | 			for ( i in postProcessing.replace ) {
126 | 				value = postProcessing.replace[i].substr(postProcessing.replace[i].length-3) == '.js' ?
127 | 					fs.readFileSync('src/' + postProcessing.replace[i]) :
128 | 					postProcessing.replace[i];
129 | 
130 | 				var regex = new RegExp('\\/\\* REPLACE START: ' + i + ' \\*\\/[\\s\\S]*\\/\\* REPLACE END: ' + i + ' \\*\\/');
131 | 				out = out.replace(regex, '/* REPLACE START: ' + i + ' */' + value + '/* REPLACE END: ' + i + ' */');
132 | 			}
133 | 		});
134 | 	}
135 | 
136 | 	// Write build file
137 | 	var buildFile = './build/iscroll' + (release != 'iscroll' ? '-' + release : '') + '.js';
138 | 	fs.writeFileSync(buildFile, out);
139 | 
140 | 	// JSHint
141 | 	if ( !hint(out) ) {
142 | 		var lines = out.split('\n');
143 | 		hint.errors.forEach(function (err) {
144 | 			console.log('\033[31m[' + err.code + ']\033[0m ' + err.line + ':' + err.character + '\t- ' + err.reason);
145 | 			console.log('\033[33m' + lines[err.line-1].replace(/\t/g, ' ') + '\033[0m\n');
146 | 		});
147 | 
148 | 		process.exit();
149 | 	}
150 | 
151 | 	// Write dist file
152 | 	var distFile = buildFile.replace('/build/', '/dist/').replace('.js', '-min.js');
153 | 	out = uglify.minify(out, { fromString: true });
154 | 
155 | 	// Make sure dist folder exists
156 | 	if ( !fs.existsSync('dist') ) {
157 | 		fs.mkdirSync('dist');
158 | 	}
159 | 
160 | 	// Write files to target
161 | 	fs.writeFileSync(distFile, banner + out.code);
162 | }
163 | 


--------------------------------------------------------------------------------
/demos/2d-scroll/index.html:
--------------------------------------------------------------------------------
  1 | <!DOCTYPE html>
  2 | <html>
  3 | <head>
  4 | <meta charset="utf-8">
  5 | <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=0, minimum-scale=1.0, maximum-scale=1.0">
  6 | 
  7 | <title>iScroll demo: 2d scroll</title>
  8 | 
  9 | <script type="text/javascript" src="../../build/iscroll.js"></script>
 10 | <script type="text/javascript" src="../demoUtils.js"></script>
 11 | <script type="text/javascript">
 12 | 
 13 | var myScroll;
 14 | 
 15 | function loaded () {
 16 | 	myScroll = new IScroll('#wrapper', { scrollX: true, freeScroll: true });
 17 | }
 18 | 
 19 | document.addEventListener('touchmove', function (e) { e.preventDefault(); }, isPassive() ? {
 20 | 	capture: false,
 21 | 	passive: false
 22 | } : false);
 23 | 
 24 | </script>
 25 | 
 26 | <style type="text/css">
 27 | * {
 28 | 	-webkit-box-sizing: border-box;
 29 | 	-moz-box-sizing: border-box;
 30 | 	box-sizing: border-box;
 31 | }
 32 | 
 33 | html {
 34 | 	-ms-touch-action: none;
 35 | }
 36 | 
 37 | body,ul,li {
 38 | 	padding: 0;
 39 | 	margin: 0;
 40 | 	border: 0;
 41 | }
 42 | 
 43 | body {
 44 | 	font-size: 12px;
 45 | 	font-family: ubuntu, helvetica, arial;
 46 | 	overflow: hidden; /* this is important to prevent the whole page to bounce */
 47 | }
 48 | 
 49 | #header {
 50 | 	position: absolute;
 51 | 	z-index: 2;
 52 | 	top: 0;
 53 | 	left: 0;
 54 | 	width: 100%;
 55 | 	height: 45px;
 56 | 	line-height: 45px;
 57 | 	background: #CD235C;
 58 | 	padding: 0;
 59 | 	color: #eee;
 60 | 	font-size: 20px;
 61 | 	text-align: center;
 62 | 	font-weight: bold;
 63 | }
 64 | 
 65 | #footer {
 66 | 	position: absolute;
 67 | 	z-index: 2;
 68 | 	bottom: 0;
 69 | 	left: 0;
 70 | 	width: 100%;
 71 | 	height: 48px;
 72 | 	background: #444;
 73 | 	padding: 0;
 74 | 	border-top: 1px solid #444;
 75 | }
 76 | 
 77 | #wrapper {
 78 | 	position: absolute;
 79 | 	z-index: 1;
 80 | 	top: 45px;
 81 | 	bottom: 48px;
 82 | 	left: 0;
 83 | 	width: 100%;
 84 | 	background: #ccc;
 85 | 	overflow: hidden;
 86 | }
 87 | 
 88 | #scroller {
 89 | 	position: absolute;
 90 | 	z-index: 1;
 91 | 	-webkit-tap-highlight-color: rgba(0,0,0,0);
 92 | 	width: 2000px;
 93 | 	-webkit-transform: translateZ(0);
 94 | 	-moz-transform: translateZ(0);
 95 | 	-ms-transform: translateZ(0);
 96 | 	-o-transform: translateZ(0);
 97 | 	transform: translateZ(0);
 98 | 	-webkit-touch-callout: none;
 99 | 	-webkit-user-select: none;
100 | 	-moz-user-select: none;
101 | 	-ms-user-select: none;
102 | 	user-select: none;
103 | 	-webkit-text-size-adjust: none;
104 | 	-moz-text-size-adjust: none;
105 | 	-ms-text-size-adjust: none;
106 | 	-o-text-size-adjust: none;
107 | 	text-size-adjust: none;
108 | 	background: #fff;
109 | }
110 | 
111 | p {
112 | 	font-size: 16px;
113 | 	padding: 1.2em;
114 | 	line-height: 200%;
115 | }
116 | 
117 | </style>
118 | </head>
119 | <body onload="loaded()">
120 | <div id="header">iScroll</div>
121 | 
122 | <div id="wrapper">
123 | 	<div id="scroller">
124 | 		<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
125 | 
126 | 		<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
127 | 
128 | 		<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
129 | 
130 | 		<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
131 | 
132 | 		<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
133 | 
134 | 		<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
135 | 	</div>
136 | </div>
137 | 
138 | <div id="footer"></div>
139 | 
140 | </body>
141 | </html>


--------------------------------------------------------------------------------
/demos/barebone/index.html:
--------------------------------------------------------------------------------
 1 | <!DOCTYPE html>
 2 | <html>
 3 | <head>
 4 | <meta charset="utf-8">
 5 | <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=0, minimum-scale=1.0, maximum-scale=1.0">
 6 | 
 7 | <title>iScroll demo: barebone</title>
 8 | 
 9 | <script type="text/javascript" src="../../build/iscroll.js"></script>
10 | <script type="text/javascript" src="../demoUtils.js"></script>
11 | <script type="text/javascript">
12 | 
13 | var myScroll;
14 | 
15 | function loaded () {
16 | 	myScroll = new IScroll('#wrapper');
17 | }
18 | 
19 | document.addEventListener('touchmove', function (e) { e.preventDefault(); }, isPassive() ? {
20 | 	capture: false,
21 | 	passive: false
22 | } : false);
23 | 
24 | </script>
25 | 
26 | <style>
27 | body {
28 | 	/* On modern browsers, prevent the whole page to bounce */
29 | 	overflow: hidden;
30 | }
31 | 
32 | #wrapper {
33 | 	position: relative;
34 | 	width: 300px;
35 | 	height: 300px;
36 | 	overflow: hidden;
37 | 
38 | 	/* Prevent native touch events on Windows */
39 | 	-ms-touch-action: none;
40 | 
41 | 	/* Prevent the callout on tap-hold and text selection */
42 | 	-webkit-touch-callout: none;
43 | 	-webkit-user-select: none;
44 | 	-moz-user-select: none;
45 | 	-ms-user-select: none;
46 | 	user-select: none;
47 | 
48 | 	/* Prevent text resize on orientation change, useful for web-apps */
49 | 	-webkit-text-size-adjust: none;
50 | 	-moz-text-size-adjust: none;
51 | 	-ms-text-size-adjust: none;
52 | 	-o-text-size-adjust: none;
53 | 	text-size-adjust: none;
54 | }
55 | 
56 | #scroller {
57 | 	position: absolute;
58 | 
59 | 	/* Prevent elements to be highlighted on tap */
60 | 	-webkit-tap-highlight-color: rgba(0,0,0,0);
61 | 
62 | 	/* Put the scroller into the HW Compositing layer right from the start */
63 | 	-webkit-transform: translateZ(0);
64 | 	-moz-transform: translateZ(0);
65 | 	-ms-transform: translateZ(0);
66 | 	-o-transform: translateZ(0);
67 | 	transform: translateZ(0);
68 | }
69 | </style>
70 | 
71 | </head>
72 | <body onload="loaded()">
73 | 
74 | <div id="wrapper">
75 | 	<div id="scroller">
76 | 		<p><strong>This demo shows the minimum CSS/HTML/JS configuration you need to run the iScroll. Look at the source code for details.</strong></p>
77 | 
78 | 		<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
79 | 
80 | 		<p>Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque laudantium, totam rem aperiam, eaque ipsa quae ab illo inventore veritatis et quasi architecto beatae vitae dicta sunt explicabo. Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugit, sed quia consequuntur magni dolores eos qui ratione voluptatem sequi nesciunt. Neque porro quisquam est, qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit, sed quia non numquam eius modi tempora incidunt ut labore et dolore magnam aliquam quaerat voluptatem. Ut enim ad minima veniam, quis nostrum exercitationem ullam corporis suscipit laboriosam, nisi ut aliquid ex ea commodi consequatur? Quis autem vel eum iure reprehenderit qui in ea voluptate velit esse quam nihil molestiae consequatur, vel illum qui dolorem eum fugiat quo voluptas nulla pariatur?</p>
81 | 
82 | 		<p>At vero eos et accusamus et iusto odio dignissimos ducimus qui blanditiis praesentium voluptatum deleniti atque corrupti quos dolores et quas molestias excepturi sint occaecati cupiditate non provident, similique sunt in culpa qui officia deserunt mollitia animi, id est laborum et dolorum fuga. Et harum quidem rerum facilis est et expedita distinctio. Nam libero tempore, cum soluta nobis est eligendi optio cumque nihil impedit quo minus id quod maxime placeat facere possimus, omnis voluptas assumenda est, omnis dolor repellendus. Temporibus autem quibusdam et aut officiis debitis aut rerum necessitatibus saepe eveniet ut et voluptates repudiandae sint et molestiae non recusandae. Itaque earum rerum hic tenetur a sapiente delectus, ut aut reiciendis voluptatibus maiores alias consequatur aut perferendis doloribus asperiores repellat.</p>
83 | 	</div>
84 | </div>
85 | 
86 | </body>
87 | </html>


--------------------------------------------------------------------------------
/demos/bounce-easing/index.html:
--------------------------------------------------------------------------------
  1 | <!DOCTYPE html>
  2 | <html>
  3 | <head>
  4 | <meta charset="utf-8">
  5 | <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=0, minimum-scale=1.0, maximum-scale=1.0">
  6 | 
  7 | <title>iScroll demo: bounce easing</title>
  8 | 
  9 | <script type="text/javascript" src="../../build/iscroll.js"></script>
 10 | <script type="text/javascript" src="../demoUtils.js"></script>
 11 | <script type="text/javascript">
 12 | 
 13 | var myScroll;
 14 | 
 15 | function loaded () {
 16 | 	myScroll = new IScroll('#wrapper', { bounceEasing: 'elastic', bounceTime: 1200 });
 17 | }
 18 | 
 19 | document.addEventListener('touchmove', function (e) { e.preventDefault(); }, isPassive() ? {
 20 | 	capture: false,
 21 | 	passive: false
 22 | } : false);
 23 | 
 24 | </script>
 25 | 
 26 | <style type="text/css">
 27 | * {
 28 | 	-webkit-box-sizing: border-box;
 29 | 	-moz-box-sizing: border-box;
 30 | 	box-sizing: border-box;
 31 | }
 32 | 
 33 | html {
 34 | 	-ms-touch-action: none;
 35 | }
 36 | 
 37 | body,ul,li {
 38 | 	padding: 0;
 39 | 	margin: 0;
 40 | 	border: 0;
 41 | }
 42 | 
 43 | body {
 44 | 	font-size: 12px;
 45 | 	font-family: ubuntu, helvetica, arial;
 46 | 	overflow: hidden; /* this is important to prevent the whole page to bounce */
 47 | }
 48 | 
 49 | #header {
 50 | 	position: absolute;
 51 | 	z-index: 2;
 52 | 	top: 0;
 53 | 	left: 0;
 54 | 	width: 100%;
 55 | 	height: 45px;
 56 | 	line-height: 45px;
 57 | 	background: #CD235C;
 58 | 	padding: 0;
 59 | 	color: #eee;
 60 | 	font-size: 20px;
 61 | 	text-align: center;
 62 | 	font-weight: bold;
 63 | }
 64 | 
 65 | #footer {
 66 | 	position: absolute;
 67 | 	z-index: 2;
 68 | 	bottom: 0;
 69 | 	left: 0;
 70 | 	width: 100%;
 71 | 	height: 48px;
 72 | 	background: #444;
 73 | 	padding: 0;
 74 | 	border-top: 1px solid #444;
 75 | }
 76 | 
 77 | #wrapper {
 78 | 	position: absolute;
 79 | 	z-index: 1;
 80 | 	top: 45px;
 81 | 	bottom: 48px;
 82 | 	left: 0;
 83 | 	width: 100%;
 84 | 	background: #ccc;
 85 | 	overflow: hidden;
 86 | }
 87 | 
 88 | #scroller {
 89 | 	position: absolute;
 90 | 	z-index: 1;
 91 | 	-webkit-tap-highlight-color: rgba(0,0,0,0);
 92 | 	width: 100%;
 93 | 	-webkit-transform: translateZ(0);
 94 | 	-moz-transform: translateZ(0);
 95 | 	-ms-transform: translateZ(0);
 96 | 	-o-transform: translateZ(0);
 97 | 	transform: translateZ(0);
 98 | 	-webkit-touch-callout: none;
 99 | 	-webkit-user-select: none;
100 | 	-moz-user-select: none;
101 | 	-ms-user-select: none;
102 | 	user-select: none;
103 | 	-webkit-text-size-adjust: none;
104 | 	-moz-text-size-adjust: none;
105 | 	-ms-text-size-adjust: none;
106 | 	-o-text-size-adjust: none;
107 | 	text-size-adjust: none;
108 | }
109 | 
110 | #scroller ul {
111 | 	list-style: none;
112 | 	padding: 0;
113 | 	margin: 0;
114 | 	width: 100%;
115 | 	text-align: left;
116 | }
117 | 
118 | #scroller li {
119 | 	padding: 0 10px;
120 | 	height: 40px;
121 | 	line-height: 40px;
122 | 	border-bottom: 1px solid #ccc;
123 | 	border-top: 1px solid #fff;
124 | 	background-color: #fafafa;
125 | 	font-size: 14px;
126 | }
127 | 
128 | </style>
129 | </head>
130 | <body onload="loaded()">
131 | <div id="header">iScroll</div>
132 | 
133 | <div id="wrapper">
134 | 	<div id="scroller">
135 | 		<ul>
136 | 			<li>Pretty row 1</li>
137 | 			<li>Pretty row 2</li>
138 | 			<li>Pretty row 3</li>
139 | 			<li>Pretty row 4</li>
140 | 			<li>Pretty row 5</li>
141 | 			<li>Pretty row 6</li>
142 | 			<li>Pretty row 7</li>
143 | 			<li>Pretty row 8</li>
144 | 			<li>Pretty row 9</li>
145 | 			<li>Pretty row 10</li>
146 | 			<li>Pretty row 11</li>
147 | 			<li>Pretty row 12</li>
148 | 			<li>Pretty row 13</li>
149 | 			<li>Pretty row 14</li>
150 | 			<li>Pretty row 15</li>
151 | 			<li>Pretty row 16</li>
152 | 			<li>Pretty row 17</li>
153 | 			<li>Pretty row 18</li>
154 | 			<li>Pretty row 19</li>
155 | 			<li>Pretty row 20</li>
156 | 			<li>Pretty row 21</li>
157 | 			<li>Pretty row 22</li>
158 | 			<li>Pretty row 23</li>
159 | 			<li>Pretty row 24</li>
160 | 			<li>Pretty row 25</li>
161 | 			<li>Pretty row 26</li>
162 | 			<li>Pretty row 27</li>
163 | 			<li>Pretty row 28</li>
164 | 			<li>Pretty row 29</li>
165 | 			<li>Pretty row 30</li>
166 | 			<li>Pretty row 31</li>
167 | 			<li>Pretty row 32</li>
168 | 			<li>Pretty row 33</li>
169 | 			<li>Pretty row 34</li>
170 | 			<li>Pretty row 35</li>
171 | 			<li>Pretty row 36</li>
172 | 			<li>Pretty row 37</li>
173 | 			<li>Pretty row 38</li>
174 | 			<li>Pretty row 39</li>
175 | 			<li>Pretty row 40</li>
176 | 			<li>Pretty row 41</li>
177 | 			<li>Pretty row 42</li>
178 | 			<li>Pretty row 43</li>
179 | 			<li>Pretty row 44</li>
180 | 			<li>Pretty row 45</li>
181 | 			<li>Pretty row 46</li>
182 | 			<li>Pretty row 47</li>
183 | 			<li>Pretty row 48</li>
184 | 			<li>Pretty row 49</li>
185 | 			<li>Pretty row 50</li>
186 | 		</ul>
187 | 	</div>
188 | </div>
189 | 
190 | <div id="footer"></div>
191 | 
192 | </body>
193 | </html>


--------------------------------------------------------------------------------
/demos/carousel/gaugin.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cubiq/iscroll/60ed6f8029b2e097a87399a2b3c688afd596980f/demos/carousel/gaugin.jpg


--------------------------------------------------------------------------------
/demos/carousel/giotto.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cubiq/iscroll/60ed6f8029b2e097a87399a2b3c688afd596980f/demos/carousel/giotto.jpg


--------------------------------------------------------------------------------
/demos/carousel/index.html:
--------------------------------------------------------------------------------
  1 | <!DOCTYPE html>
  2 | <html>
  3 | <head>
  4 | <meta charset="utf-8">
  5 | <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=0, minimum-scale=1.0, maximum-scale=1.0">
  6 | 
  7 | <title>iScroll demo: carousel</title>
  8 | 
  9 | <script type="text/javascript" src="../../build/iscroll.js"></script>
 10 | <script type="text/javascript" src="../demoUtils.js"></script>
 11 | <script type="text/javascript">
 12 | 
 13 | var myScroll;
 14 | 
 15 | function loaded () {
 16 | 	myScroll = new IScroll('#wrapper', {
 17 | 		scrollX: true,
 18 | 		scrollY: false,
 19 | 		momentum: false,
 20 | 		snap: true,
 21 | 		snapSpeed: 400,
 22 | 		keyBindings: true,
 23 | 		indicators: {
 24 | 			el: document.getElementById('indicator'),
 25 | 			resize: false
 26 | 		}
 27 | 	});
 28 | }
 29 | 
 30 | document.addEventListener('touchmove', function (e) { e.preventDefault(); }, isPassive() ? {
 31 | 	capture: false,
 32 | 	passive: false
 33 | } : false);
 34 | </script>
 35 | 
 36 | <style type="text/css">
 37 | * {
 38 | 	-webkit-box-sizing: border-box;
 39 | 	-moz-box-sizing: border-box;
 40 | 	box-sizing: border-box;
 41 | }
 42 | 
 43 | html {
 44 | 	-ms-touch-action: none;
 45 | }
 46 | 
 47 | body, ul, li {
 48 | 	padding: 0;
 49 | 	margin: 0;
 50 | 	border: 0;
 51 | }
 52 | 
 53 | body {
 54 | 	font-size: 12px;
 55 | 	font-family: ubuntu, helvetica, arial;
 56 | 	overflow: hidden; /* this is important to prevent the whole page to bounce */
 57 | }
 58 | 
 59 | #viewport {
 60 | 	position: relative;
 61 | 	width: 320px;
 62 | 	height: 240px;
 63 | 	margin: 0 auto;
 64 | 	background: #444;
 65 | 	overflow: hidden;
 66 | }
 67 | 
 68 | #wrapper {
 69 | 	width: 200px;
 70 | 	height: 240px;
 71 | 	margin: 0 auto;
 72 | }
 73 | 
 74 | #scroller {
 75 | 	position: absolute;
 76 | 	z-index: 1;
 77 | 	-webkit-tap-highlight-color: rgba(0,0,0,0);
 78 | 	width: 800px;
 79 | 	height: 240px;
 80 | 	-webkit-transform: translateZ(0);
 81 | 	-moz-transform: translateZ(0);
 82 | 	-ms-transform: translateZ(0);
 83 | 	-o-transform: translateZ(0);
 84 | 	transform: translateZ(0);
 85 | 	-webkit-touch-callout: none;
 86 | 	-webkit-user-select: none;
 87 | 	-moz-user-select: none;
 88 | 	-ms-user-select: none;
 89 | 	user-select: none;
 90 | 	-webkit-text-size-adjust: none;
 91 | 	-moz-text-size-adjust: none;
 92 | 	-ms-text-size-adjust: none;
 93 | 	-o-text-size-adjust: none;
 94 | 	text-size-adjust: none;
 95 | 	background-color: #444;
 96 | }
 97 | 
 98 | .slide {
 99 | 	width: 200px;
100 | 	height: 240px;
101 | 	float: left;
102 | }
103 | 
104 | .painting {
105 | 	width: 140px;
106 | 	height: 200px;
107 | 	border-radius: 10px;
108 | 	margin: 20px auto;
109 | 	border: 1px solid #000;
110 | 	box-shadow:
111 | 		inset 2px 2px 6px rgba(255,255,255,0.6),
112 | 		inset -2px -2px 6px rgba(0,0,0,0.6),
113 | 		0 1px 8px rgba(0,0,0,0.8);
114 | }
115 | 
116 | .giotto {
117 | 	background: url(giotto.jpg);
118 | }
119 | 
120 | .leonardo {
121 | 	background: url(leonardo.jpg);
122 | }
123 | 
124 | .gaugin {
125 | 	background: url(gaugin.jpg);
126 | }
127 | 
128 | .warhol {
129 | 	background: url(warhol.jpg);
130 | }
131 | 
132 | #indicator {
133 | 	position: relative;
134 | 	width: 110px;
135 | 	height: 20px;
136 | 	margin: 10px auto;
137 | 	background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAB4AAAAUBAMAAABohZD3AAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH3QUGCDYztyDUJgAAAB1pVFh0Q29tbWVudAAAAAAAQ3JlYXRlZCB3aXRoIEdJTVBkLmUHAAAAGFBMVEUAAADNzc3Nzc3Nzc3Nzc3Nzc3Nzc3///8aWwwLAAAABnRSTlMAX5Ks3/nRD0HIAAAAAWJLR0QHFmGI6wAAAFtJREFUGFdjYGBgEHYNMWRAAJE0IHCEc5nSwEABxleD8JOgXMY0KBCA8FlgfAcIXwzGT4TwzWD8ZAjfDcZPgfDDYPxU7Hx09ejmoduH7h5096L7B8O/6OGBGl4APYg8TQ0XAScAAAAASUVORK5CYII=);
138 | }
139 | 
140 | #dotty {
141 | 	position: absolute;
142 | 	width: 20px;
143 | 	height: 20px;
144 | 	border-radius: 10px;
145 | 	background: #777;
146 | }
147 | 
148 | </style>
149 | </head>
150 | <body onload="loaded()">
151 | 
152 | <div id="viewport">
153 | 	<div id="wrapper">
154 | 		<div id="scroller">
155 | 			<div class="slide">
156 | 				<div class="painting giotto"></div>
157 | 			</div>
158 | 			<div class="slide">
159 | 				<div class="painting leonardo"></div>
160 | 			</div>
161 | 			<div class="slide">
162 | 				<div class="painting gaugin"></div>
163 | 			</div>
164 | 			<div class="slide">
165 | 				<div class="painting warhol"></div>
166 | 			</div>
167 | 		</div>
168 | 	</div>
169 | </div>
170 | 
171 | <div id="indicator">
172 | 	<div id="dotty"></div>
173 | </div>
174 | 
175 | </body>
176 | </html>


--------------------------------------------------------------------------------
/demos/carousel/leonardo.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cubiq/iscroll/60ed6f8029b2e097a87399a2b3c688afd596980f/demos/carousel/leonardo.jpg


--------------------------------------------------------------------------------
/demos/carousel/warhol.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cubiq/iscroll/60ed6f8029b2e097a87399a2b3c688afd596980f/demos/carousel/warhol.jpg


--------------------------------------------------------------------------------
/demos/click/index.html:
--------------------------------------------------------------------------------
  1 | <!DOCTYPE html>
  2 | <html>
  3 | <head>
  4 | <meta charset="utf-8">
  5 | <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=0, minimum-scale=1.0, maximum-scale=1.0">
  6 | 
  7 | <title>iScroll demo: click</title>
  8 | 
  9 | <script type="text/javascript" src="../../build/iscroll.js"></script>
 10 | <script type="text/javascript" src="../demoUtils.js"></script>
 11 | <script type="text/javascript">
 12 | 
 13 | var myScroll;
 14 | 
 15 | function loaded () {
 16 | 	myScroll = new IScroll('#wrapper', { mouseWheel: true, click: true });
 17 | }
 18 | 
 19 | document.addEventListener('touchmove', function (e) { e.preventDefault(); }, isPassive() ? {
 20 | 	capture: false,
 21 | 	passive: false
 22 | } : false);
 23 | 
 24 | </script>
 25 | 
 26 | <style type="text/css">
 27 | * {
 28 | 	-webkit-box-sizing: border-box;
 29 | 	-moz-box-sizing: border-box;
 30 | 	box-sizing: border-box;
 31 | }
 32 | 
 33 | html {
 34 | 	-ms-touch-action: none;
 35 | }
 36 | 
 37 | body,ul,li {
 38 | 	padding: 0;
 39 | 	margin: 0;
 40 | 	border: 0;
 41 | }
 42 | 
 43 | body {
 44 | 	font-size: 12px;
 45 | 	font-family: ubuntu, helvetica, arial;
 46 | 	overflow: hidden; /* this is important to prevent the whole page to bounce */
 47 | }
 48 | 
 49 | #header {
 50 | 	position: absolute;
 51 | 	z-index: 2;
 52 | 	top: 0;
 53 | 	left: 0;
 54 | 	width: 100%;
 55 | 	height: 45px;
 56 | 	line-height: 45px;
 57 | 	background: #CD235C;
 58 | 	padding: 0;
 59 | 	color: #eee;
 60 | 	font-size: 20px;
 61 | 	text-align: center;
 62 | 	font-weight: bold;
 63 | }
 64 | 
 65 | #footer {
 66 | 	position: absolute;
 67 | 	z-index: 2;
 68 | 	bottom: 0;
 69 | 	left: 0;
 70 | 	width: 100%;
 71 | 	height: 48px;
 72 | 	background: #444;
 73 | 	padding: 0;
 74 | 	border-top: 1px solid #444;
 75 | }
 76 | 
 77 | #wrapper {
 78 | 	position: absolute;
 79 | 	z-index: 1;
 80 | 	top: 45px;
 81 | 	bottom: 48px;
 82 | 	left: 0;
 83 | 	width: 100%;
 84 | 	background: #ccc;
 85 | 	overflow: hidden;
 86 | }
 87 | 
 88 | #scroller {
 89 | 	position: absolute;
 90 | 	z-index: 1;
 91 | 	-webkit-tap-highlight-color: rgba(0,0,0,0);
 92 | 	width: 100%;
 93 | 	-webkit-transform: translateZ(0);
 94 | 	-moz-transform: translateZ(0);
 95 | 	-ms-transform: translateZ(0);
 96 | 	-o-transform: translateZ(0);
 97 | 	transform: translateZ(0);
 98 | 	-webkit-touch-callout: none;
 99 | 	-webkit-user-select: none;
100 | 	-moz-user-select: none;
101 | 	-ms-user-select: none;
102 | 	user-select: none;
103 | 	-webkit-text-size-adjust: none;
104 | 	-moz-text-size-adjust: none;
105 | 	-ms-text-size-adjust: none;
106 | 	-o-text-size-adjust: none;
107 | 	text-size-adjust: none;
108 | }
109 | 
110 | #scroller ul {
111 | 	list-style: none;
112 | 	padding: 0;
113 | 	margin: 0;
114 | 	width: 100%;
115 | 	text-align: left;
116 | }
117 | 
118 | #scroller li {
119 | 	padding: 0 10px;
120 | 	height: 40px;
121 | 	line-height: 40px;
122 | 	border-bottom: 1px solid #ccc;
123 | 	border-top: 1px solid #fff;
124 | 	background-color: #fafafa;
125 | 	font-size: 14px;
126 | }
127 | 
128 | </style>
129 | </head>
130 | <body onload="loaded()">
131 | <div id="header">iScroll</div>
132 | 
133 | <div id="wrapper">
134 | 	<div id="scroller">
135 | 		<ul>
136 | 			<li>Pretty row 1</li>
137 | 			<li>Pretty row 2</li>
138 | 			<li>Pretty row 3</li>
139 | 			<li>Pretty row 4</li>
140 | 			<li>Pretty row 5</li>
141 | 			<li id="me"><a href="#" onclick="console.log(this.parentNode.style.backgroundColor);this.parentNode.style.backgroundColor=this.parentNode.style.backgroundColor==''?'#a00':'';return false">Click me!</a></li>
142 | 			<li>Pretty row 7</li>
143 | 			<li>Pretty row 8</li>
144 | 			<li>Pretty row 9</li>
145 | 			<li>Pretty row 10</li>
146 | 			<li>Pretty row 11</li>
147 | 			<li>Pretty row 12</li>
148 | 			<li>Pretty row 13</li>
149 | 			<li>Pretty row 14</li>
150 | 			<li>Pretty row 15</li>
151 | 			<li>Pretty row 16</li>
152 | 			<li>Pretty row 17</li>
153 | 			<li>Pretty row 18</li>
154 | 			<li>Pretty row 19</li>
155 | 			<li>Pretty row 20</li>
156 | 			<li>Pretty row 21</li>
157 | 			<li>Pretty row 22</li>
158 | 			<li>Pretty row 23</li>
159 | 			<li>Pretty row 24</li>
160 | 			<li>Pretty row 25</li>
161 | 			<li>Pretty row 26</li>
162 | 			<li>Pretty row 27</li>
163 | 			<li>Pretty row 28</li>
164 | 			<li>Pretty row 29</li>
165 | 			<li>Pretty row 30</li>
166 | 			<li>Pretty row 31</li>
167 | 			<li>Pretty row 32</li>
168 | 			<li>Pretty row 33</li>
169 | 			<li>Pretty row 34</li>
170 | 			<li>Pretty row 35</li>
171 | 			<li>Pretty row 36</li>
172 | 			<li>Pretty row 37</li>
173 | 			<li>Pretty row 38</li>
174 | 			<li>Pretty row 39</li>
175 | 			<li>Pretty row 40</li>
176 | 			<li>Pretty row 41</li>
177 | 			<li>Pretty row 42</li>
178 | 			<li>Pretty row 43</li>
179 | 			<li>Pretty row 44</li>
180 | 			<li>Pretty row 45</li>
181 | 			<li>Pretty row 46</li>
182 | 			<li>Pretty row 47</li>
183 | 			<li>Pretty row 48</li>
184 | 			<li>Pretty row 49</li>
185 | 			<li>Pretty row 50</li>
186 | 		</ul>
187 | 	</div>
188 | </div>
189 | 
190 | <div id="footer"></div>
191 | 
192 | </body>
193 | </html>


--------------------------------------------------------------------------------
/demos/demoUtils.js:
--------------------------------------------------------------------------------
 1 | // ref https://github.com/WICG/EventListenerOptions/pull/30
 2 | function isPassive() {
 3 |     var supportsPassiveOption = false;
 4 |     try {
 5 |         addEventListener("test", null, Object.defineProperty({}, 'passive', {
 6 |             get: function () {
 7 |                 supportsPassiveOption = true;
 8 |             }
 9 |         }));
10 |     } catch(e) {}
11 |     return supportsPassiveOption;
12 | }
13 |   		  


--------------------------------------------------------------------------------
/demos/event-passthrough/index.html:
--------------------------------------------------------------------------------
  1 | <!DOCTYPE html>
  2 | <html>
  3 | <head>
  4 | <meta charset="utf-8">
  5 | <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=0, minimum-scale=1.0, maximum-scale=1.0">
  6 | 
  7 | <title>iScroll demo: Event Passthrough</title>
  8 | 
  9 | <script type="text/javascript" src="../../build/iscroll.js"></script>
 10 | 
 11 | <script type="text/javascript">
 12 | 
 13 | var myScroll;
 14 | 
 15 | function loaded () {
 16 | 	myScroll = new IScroll('#wrapper', { eventPassthrough: true, scrollX: true, scrollY: false, preventDefault: false });
 17 | }
 18 | 
 19 | </script>
 20 | 
 21 | <style type="text/css">
 22 | * {
 23 | 	-webkit-box-sizing: border-box;
 24 | 	-moz-box-sizing: border-box;
 25 | 	box-sizing: border-box;
 26 | }
 27 | 
 28 | body,ul,li {
 29 | 	padding: 0;
 30 | 	margin: 0;
 31 | 	border: 0;
 32 | }
 33 | 
 34 | body {
 35 | 	font-size: 12px;
 36 | 	font-family: ubuntu, helvetica, arial;
 37 | }
 38 | 
 39 | #header {
 40 | 	width: 100%;
 41 | 	height: 45px;
 42 | 	line-height: 45px;
 43 | 	background: #CD235C;
 44 | 	padding: 0;
 45 | 	color: #eee;
 46 | 	font-size: 20px;
 47 | 	text-align: center;
 48 | 	font-weight: bold;
 49 | }
 50 | 
 51 | #wrapper {
 52 | 	position: relative;
 53 | 	z-index: 1;
 54 | 	height: 160px;
 55 | 	width: 100%;
 56 | 	background: #ccc;
 57 | 	overflow: hidden;
 58 | 	-ms-touch-action: none;
 59 | }
 60 | 
 61 | #scroller {
 62 | 	position: absolute;
 63 | 	z-index: 1;
 64 | 	-webkit-tap-highlight-color: rgba(0,0,0,0);
 65 | 	width: 2400px;
 66 | 	height: 160px;
 67 | 	-webkit-transform: translateZ(0);
 68 | 	-moz-transform: translateZ(0);
 69 | 	-ms-transform: translateZ(0);
 70 | 	-o-transform: translateZ(0);
 71 | 	transform: translateZ(0);
 72 | 	-webkit-touch-callout: none;
 73 | 	-webkit-user-select: none;
 74 | 	-moz-user-select: none;
 75 | 	-ms-user-select: none;
 76 | 	user-select: none;
 77 | 	-webkit-text-size-adjust: none;
 78 | 	-moz-text-size-adjust: none;
 79 | 	-ms-text-size-adjust: none;
 80 | 	-o-text-size-adjust: none;
 81 | 	text-size-adjust: none;
 82 | }
 83 | 
 84 | #scroller ul {
 85 | 	list-style: none;
 86 | 	width: 100%;
 87 | 	padding: 0;
 88 | 	margin: 0;
 89 | }
 90 | 
 91 | #scroller li {
 92 | 	width: 120px;
 93 | 	height: 160px;
 94 | 	float: left;
 95 | 	line-height: 160px;
 96 | 	border-right: 1px solid #ccc;
 97 | 	border-bottom: 1px solid #ccc;
 98 | 	background-color: #fafafa;
 99 | 	font-size: 14px;
100 | 	overflow: hidden;
101 | 	text-align: center;
102 | }
103 | 
104 | p {
105 | 	font-size: 16px;
106 | 	padding: 1.2em;
107 | 	line-height: 200%;
108 | }
109 | 
110 | </style>
111 | </head>
112 | <body onload="loaded()">
113 | <div id="header">iScroll</div>
114 | 
115 | <div id="wrapper">
116 | 	<div id="scroller">
117 | 		<ul>
118 | 			<li>Pretty cell 1</li>
119 | 			<li>Pretty cell 2</li>
120 | 			<li>Pretty cell 3</li>
121 | 			<li>Pretty cell 4</li>
122 | 			<li>Pretty cell 5</li>
123 | 			<li>Pretty cell 6</li>
124 | 			<li>Pretty cell 7</li>
125 | 			<li>Pretty cell 8</li>
126 | 			<li>Pretty cell 9</li>
127 | 			<li>Pretty cell 10</li>
128 | 			<li>Pretty cell 11</li>
129 | 			<li>Pretty cell 12</li>
130 | 			<li>Pretty cell 13</li>
131 | 			<li>Pretty cell 14</li>
132 | 			<li>Pretty cell 15</li>
133 | 			<li>Pretty cell 16</li>
134 | 			<li>Pretty cell 17</li>
135 | 			<li>Pretty cell 18</li>
136 | 			<li>Pretty cell 19</li>
137 | 			<li>Pretty cell 20</li>
138 | 		</ul>
139 | 	</div>
140 | </div>
141 | 
142 | <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
143 | 
144 | <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
145 | 
146 | <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
147 | 
148 | <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
149 | 
150 | <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
151 | 
152 | <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
153 | 
154 | </body>
155 | </html>


--------------------------------------------------------------------------------
/demos/forms/index.html:
--------------------------------------------------------------------------------
  1 | <!DOCTYPE html>
  2 | <html>
  3 | <head>
  4 | <meta charset="utf-8">
  5 | <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=0, minimum-scale=1.0, maximum-scale=1.0">
  6 | 
  7 | <title>iScroll demo: simple</title>
  8 | 
  9 | <script type="text/javascript" src="../../build/iscroll.js"></script>
 10 | <script type="text/javascript" src="../demoUtils.js"></script>
 11 | <script type="text/javascript">
 12 | 
 13 | var myScroll;
 14 | 
 15 | function loaded () {
 16 | 	myScroll = new IScroll('#wrapper', { mouseWheel: true });
 17 | }
 18 | 
 19 | document.addEventListener('touchmove', function (e) { e.preventDefault(); }, isPassive() ? {
 20 | 	capture: false,
 21 | 	passive: false
 22 | } : false);
 23 | 
 24 | </script>
 25 | 
 26 | <style type="text/css">
 27 | * {
 28 | 	-webkit-box-sizing: border-box;
 29 | 	-moz-box-sizing: border-box;
 30 | 	box-sizing: border-box;
 31 | }
 32 | 
 33 | html {
 34 | 	-ms-touch-action: none;
 35 | }
 36 | 
 37 | body,ul,li {
 38 | 	padding: 0;
 39 | 	margin: 0;
 40 | 	border: 0;
 41 | }
 42 | 
 43 | body {
 44 | 	font-size: 12px;
 45 | 	font-family: ubuntu, helvetica, arial;
 46 | 	overflow: hidden; /* this is important to prevent the whole page to bounce */
 47 | }
 48 | 
 49 | #header {
 50 | 	position: absolute;
 51 | 	z-index: 2;
 52 | 	top: 0;
 53 | 	left: 0;
 54 | 	width: 100%;
 55 | 	height: 45px;
 56 | 	line-height: 45px;
 57 | 	background: #CD235C;
 58 | 	padding: 0;
 59 | 	color: #eee;
 60 | 	font-size: 20px;
 61 | 	text-align: center;
 62 | 	font-weight: bold;
 63 | }
 64 | 
 65 | #footer {
 66 | 	position: absolute;
 67 | 	z-index: 2;
 68 | 	bottom: 0;
 69 | 	left: 0;
 70 | 	width: 100%;
 71 | 	height: 48px;
 72 | 	background: #444;
 73 | 	padding: 0;
 74 | 	border-top: 1px solid #444;
 75 | }
 76 | 
 77 | #wrapper {
 78 | 	position: absolute;
 79 | 	z-index: 1;
 80 | 	top: 45px;
 81 | 	bottom: 48px;
 82 | 	left: 0;
 83 | 	width: 100%;
 84 | 	background: #ccc;
 85 | 	overflow: hidden;
 86 | }
 87 | 
 88 | #scroller {
 89 | 	position: absolute;
 90 | 	z-index: 1;
 91 | 	-webkit-tap-highlight-color: rgba(0,0,0,0);
 92 | 	width: 100%;
 93 | 	-webkit-transform: translateZ(0);
 94 | 	-moz-transform: translateZ(0);
 95 | 	-ms-transform: translateZ(0);
 96 | 	-o-transform: translateZ(0);
 97 | 	transform: translateZ(0);
 98 | 	-webkit-touch-callout: none;
 99 | 	-webkit-user-select: none;
100 | 	-moz-user-select: none;
101 | 	-ms-user-select: none;
102 | 	user-select: none;
103 | 	-webkit-text-size-adjust: none;
104 | 	-moz-text-size-adjust: none;
105 | 	-ms-text-size-adjust: none;
106 | 	-o-text-size-adjust: none;
107 | 	text-size-adjust: none;
108 | }
109 | 
110 | #scroller ul {
111 | 	list-style: none;
112 | 	padding: 0;
113 | 	margin: 0;
114 | 	width: 100%;
115 | 	text-align: left;
116 | }
117 | 
118 | #scroller li {
119 | 	padding: 0 10px;
120 | 	height: 40px;
121 | 	line-height: 40px;
122 | 	border-bottom: 1px solid #ccc;
123 | 	border-top: 1px solid #fff;
124 | 	background-color: #fafafa;
125 | 	font-size: 14px;
126 | }
127 | 
128 | </style>
129 | </head>
130 | <body onload="loaded()">
131 | <div id="header">iScroll</div>
132 | 
133 | <div id="wrapper">
134 | 	<div id="scroller">
135 | 		<ul>
136 | 			<li>Pretty row 1</li>
137 | 			<li>Pretty row 2</li>
138 | 			<li>Pretty row 3</li>
139 | 			<li>Pretty row 4</li>
140 | 			<li><input type="text"></li>
141 | 			<li>Pretty row 6</li>
142 | 			<li>Pretty row 7</li>
143 | 			<li>Pretty row 8</li>
144 | 			<li><input type="checkbox"></li>
145 | 			<li>Pretty row 10</li>
146 | 			<li>Pretty row 11</li>
147 | 			<li>Pretty row 12</li>
148 | 			<li><input type="radio"></li>
149 | 			<li>Pretty row 14</li>
150 | 			<li>Pretty row 15</li>
151 | 			<li>Pretty row 16</li>
152 | 			<li><textarea></textarea></li>
153 | 			<li>Pretty row 18</li>
154 | 			<li>Pretty row 19</li>
155 | 			<li>Pretty row 20</li>
156 | 			<li><select><option>option</option></select></li>
157 | 			<li>Pretty row 22</li>
158 | 			<li>Pretty row 23</li>
159 | 			<li>Pretty row 24</li>
160 | 			<li>Pretty row 25</li>
161 | 			<li>Pretty row 26</li>
162 | 			<li>Pretty row 27</li>
163 | 			<li>Pretty row 28</li>
164 | 			<li>Pretty row 29</li>
165 | 			<li>Pretty row 30</li>
166 | 			<li>Pretty row 31</li>
167 | 			<li>Pretty row 32</li>
168 | 			<li>Pretty row 33</li>
169 | 			<li>Pretty row 34</li>
170 | 			<li>Pretty row 35</li>
171 | 			<li>Pretty row 36</li>
172 | 			<li>Pretty row 37</li>
173 | 			<li>Pretty row 38</li>
174 | 			<li>Pretty row 39</li>
175 | 			<li>Pretty row 40</li>
176 | 			<li>Pretty row 41</li>
177 | 			<li>Pretty row 42</li>
178 | 			<li>Pretty row 43</li>
179 | 			<li>Pretty row 44</li>
180 | 			<li>Pretty row 45</li>
181 | 			<li>Pretty row 46</li>
182 | 			<li>Pretty row 47</li>
183 | 			<li>Pretty row 48</li>
184 | 			<li>Pretty row 49</li>
185 | 			<li>Pretty row 50</li>
186 | 		</ul>
187 | 	</div>
188 | </div>
189 | 
190 | <div id="footer"></div>
191 | 
192 | </body>
193 | </html>


--------------------------------------------------------------------------------
/demos/horizontal/index.html:
--------------------------------------------------------------------------------
  1 | <!DOCTYPE html>
  2 | <html>
  3 | <head>
  4 | <meta charset="utf-8">
  5 | <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=0, minimum-scale=1.0, maximum-scale=1.0">
  6 | 
  7 | <title>iScroll demo: horizontal scrolling</title>
  8 | 
  9 | <script type="text/javascript" src="../../build/iscroll.js"></script>
 10 | <script type="text/javascript" src="../demoUtils.js"></script>
 11 | <script type="text/javascript">
 12 | 
 13 | var myScroll;
 14 | 
 15 | function loaded () {
 16 | 	myScroll = new IScroll('#wrapper', { scrollX: true, scrollY: false, mouseWheel: true });
 17 | }
 18 | 
 19 | document.addEventListener('touchmove', function (e) { e.preventDefault(); }, isPassive() ? {
 20 | 	capture: false,
 21 | 	passive: false
 22 | } : false);
 23 | 
 24 | </script>
 25 | 
 26 | <style type="text/css">
 27 | * {
 28 | 	-webkit-box-sizing: border-box;
 29 | 	-moz-box-sizing: border-box;
 30 | 	box-sizing: border-box;
 31 | }
 32 | 
 33 | html {
 34 | 	-ms-touch-action: none;
 35 | }
 36 | 
 37 | body,ul,li {
 38 | 	padding: 0;
 39 | 	margin: 0;
 40 | 	border: 0;
 41 | }
 42 | 
 43 | body {
 44 | 	font-size: 12px;
 45 | 	font-family: ubuntu, helvetica, arial;
 46 | 	overflow: hidden; /* this is important to prevent the whole page to bounce */
 47 | }
 48 | 
 49 | #header {
 50 | 	position: absolute;
 51 | 	z-index: 2;
 52 | 	top: 0;
 53 | 	left: 0;
 54 | 	width: 100%;
 55 | 	height: 45px;
 56 | 	line-height: 45px;
 57 | 	background: #CD235C;
 58 | 	padding: 0;
 59 | 	color: #eee;
 60 | 	font-size: 20px;
 61 | 	text-align: center;
 62 | 	font-weight: bold;
 63 | }
 64 | 
 65 | #footer {
 66 | 	position: absolute;
 67 | 	z-index: 2;
 68 | 	bottom: 0;
 69 | 	left: 0;
 70 | 	width: 100%;
 71 | 	height: 48px;
 72 | 	background: #444;
 73 | 	padding: 0;
 74 | 	border-top: 1px solid #444;
 75 | }
 76 | 
 77 | #wrapper {
 78 | 	position: absolute;
 79 | 	z-index: 1;
 80 | 	top: 45px;
 81 | 	bottom: 48px;
 82 | 	left: 0;
 83 | 	width: 100%;
 84 | 	background: #ccc;
 85 | 	overflow: hidden;
 86 | }
 87 | 
 88 | #scroller {
 89 | 	position: absolute;
 90 | 	z-index: 1;
 91 | 	-webkit-tap-highlight-color: rgba(0,0,0,0);
 92 | 	width: 5000px;
 93 | 	height: 100%;
 94 | 	background-color: #a00;
 95 | 	-webkit-transform: translateZ(0);
 96 | 	-moz-transform: translateZ(0);
 97 | 	-ms-transform: translateZ(0);
 98 | 	-o-transform: translateZ(0);
 99 | 	transform: translateZ(0);
100 | 	-webkit-touch-callout: none;
101 | 	-webkit-user-select: none;
102 | 	-moz-user-select: none;
103 | 	-ms-user-select: none;
104 | 	user-select: none;
105 | 	-webkit-text-size-adjust: none;
106 | 	-moz-text-size-adjust: none;
107 | 	-ms-text-size-adjust: none;
108 | 	-o-text-size-adjust: none;
109 | 	text-size-adjust: none;
110 | }
111 | 
112 | #scroller ul {
113 | 	list-style: none;
114 | 	padding: 0;
115 | 	margin: 0;
116 | 	width: 100%;
117 | 	height: 100%;
118 | 	text-align: center;
119 | }
120 | 
121 | #scroller li {
122 | 	display: block;
123 | 	float: left;
124 | 	width: 100px;
125 | 	height: 100%;
126 | 	border-right: 1px solid #ccc;
127 | 	background-color: #fafafa;
128 | 	font-size: 14px;
129 | }
130 | 
131 | </style>
132 | </head>
133 | <body onload="loaded()">
134 | <div id="header">iScroll</div>
135 | 
136 | <div id="wrapper">
137 | 	<div id="scroller">
138 | 		<ul>
139 | 			<li>Cell 1</li>
140 | 			<li>Cell 2</li>
141 | 			<li>Cell 3</li>
142 | 			<li>Cell 4</li>
143 | 			<li>Cell 5</li>
144 | 			<li>Cell 6</li>
145 | 			<li>Cell 7</li>
146 | 			<li>Cell 8</li>
147 | 			<li>Cell 9</li>
148 | 			<li>Cell 10</li>
149 | 			<li>Cell 11</li>
150 | 			<li>Cell 12</li>
151 | 			<li>Cell 13</li>
152 | 			<li>Cell 14</li>
153 | 			<li>Cell 15</li>
154 | 			<li>Cell 16</li>
155 | 			<li>Cell 17</li>
156 | 			<li>Cell 18</li>
157 | 			<li>Cell 19</li>
158 | 			<li>Cell 20</li>
159 | 			<li>Cell 21</li>
160 | 			<li>Cell 22</li>
161 | 			<li>Cell 23</li>
162 | 			<li>Cell 24</li>
163 | 			<li>Cell 25</li>
164 | 			<li>Cell 26</li>
165 | 			<li>Cell 27</li>
166 | 			<li>Cell 28</li>
167 | 			<li>Cell 29</li>
168 | 			<li>Cell 30</li>
169 | 			<li>Cell 31</li>
170 | 			<li>Cell 32</li>
171 | 			<li>Cell 33</li>
172 | 			<li>Cell 34</li>
173 | 			<li>Cell 35</li>
174 | 			<li>Cell 36</li>
175 | 			<li>Cell 37</li>
176 | 			<li>Cell 38</li>
177 | 			<li>Cell 39</li>
178 | 			<li>Cell 40</li>
179 | 			<li>Cell 41</li>
180 | 			<li>Cell 42</li>
181 | 			<li>Cell 43</li>
182 | 			<li>Cell 44</li>
183 | 			<li>Cell 45</li>
184 | 			<li>Cell 46</li>
185 | 			<li>Cell 47</li>
186 | 			<li>Cell 48</li>
187 | 			<li>Cell 49</li>
188 | 			<li>Cell 50</li>
189 | 		</ul>
190 | 	</div>
191 | </div>
192 | 
193 | <div id="footer"></div>
194 | 
195 | </body>
196 | </html>


--------------------------------------------------------------------------------
/demos/infinite/dataset.php:
--------------------------------------------------------------------------------
 1 | <?php
 2 | //header('Cache-Control: no-cache, must-revalidate');
 3 | //header('Expires: Mon, 26 Jul 1997 05:00:00 GMT');
 4 | header('Content-type: application/json');
 5 | 
 6 | $start = isset($_GET['start']) ? (int)$_GET['start'] : 0;
 7 | $count = isset($_GET['count']) ? min((int)$_GET['count'], 2000) : 100;
 8 | 
 9 | $data = array();
10 | for ( $i = $start; $i < $start+$count; $i++ ) {
11 | 	$data[] = $i;
12 | }
13 | 
14 | echo json_encode($data);
15 | 


--------------------------------------------------------------------------------
/demos/infinite/index.html:
--------------------------------------------------------------------------------
  1 | <!DOCTYPE html>
  2 | <html>
  3 | <head>
  4 | <meta charset="utf-8">
  5 | <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=0, minimum-scale=1.0, maximum-scale=1.0">
  6 | 
  7 | <title>iScroll demo: infinite scrolling</title>
  8 | 
  9 | <script type="text/javascript" src="../../build/iscroll-infinite.js"></script>
 10 | <script type="text/javascript" src="../demoUtils.js"></script>
 11 | <script type="text/javascript">
 12 | /******************************************************************************
 13 |  *
 14 |  * For the sake of keeping the script dependecy free I'm including a custom
 15 |  * AJAX function. You should probably use a third party plugin
 16 |  *
 17 |  */
 18 | function ajax (url, parms) {
 19 | 	parms = parms || {};
 20 | 	var req = new XMLHttpRequest(),
 21 | 		post = parms.post || null,
 22 | 		callback = parms.callback || null,
 23 | 		timeout = parms.timeout || null;
 24 | 
 25 | 	req.onreadystatechange = function () {
 26 | 		if ( req.readyState != 4 ) return;
 27 | 
 28 | 		// Error
 29 | 		if ( req.status != 200 && req.status != 304 ) {
 30 | 			if ( callback ) callback(false);
 31 | 			return;
 32 | 		}
 33 | 
 34 | 		if ( callback ) callback(req.responseText);
 35 | 	};
 36 | 
 37 | 	if ( post ) {
 38 | 		req.open('POST', url, true);
 39 | 		req.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');
 40 | 	} else {
 41 | 		req.open('GET', url, true);
 42 | 	}
 43 | 
 44 | 	req.setRequestHeader('X-Requested-With', 'XMLHttpRequest');
 45 | 
 46 | 	req.send(post);
 47 | 
 48 | 	if ( timeout ) {
 49 | 		setTimeout(function () {
 50 | 			req.onreadystatechange = function () {};
 51 | 			req.abort();
 52 | 			if ( callback ) callback(false);
 53 | 		}, timeout);
 54 | 	}
 55 | }
 56 | /*
 57 |  *****************************************************************************/
 58 | 
 59 | var myScroll;
 60 | 
 61 | function loaded () {
 62 | 	myScroll = new IScroll('#wrapper', {
 63 | 		mouseWheel: true,
 64 | 		infiniteElements: '#scroller .row',
 65 | 		//infiniteLimit: 2000,
 66 | 		dataset: requestData,
 67 | 		dataFiller: updateContent,
 68 | 		cacheSize: 1000
 69 | 	});
 70 | }
 71 | 
 72 | function requestData (start, count) {
 73 | 	ajax('dataset.php?start=' + +start + '&count=' + +count, {
 74 | 		callback: function (data) {
 75 | 			data = JSON.parse(data);
 76 | 			myScroll.updateCache(start, data);
 77 | 		}
 78 | 	});
 79 | }
 80 | 
 81 | function updateContent (el, data) {
 82 | 	el.innerHTML = data;
 83 | }
 84 | 
 85 | document.addEventListener('touchmove', function (e) { e.preventDefault(); }, isPassive() ? {
 86 | 	capture: false,
 87 | 	passive: false
 88 | } : false);
 89 | 
 90 | </script>
 91 | 
 92 | <style type="text/css">
 93 | * {
 94 | 	-webkit-box-sizing: border-box;
 95 | 	-moz-box-sizing: border-box;
 96 | 	box-sizing: border-box;
 97 | }
 98 | 
 99 | html {
100 | 	-ms-touch-action: none;
101 | }
102 | 
103 | body,ul,li {
104 | 	padding: 0;
105 | 	margin: 0;
106 | 	border: 0;
107 | }
108 | 
109 | body {
110 | 	font-size: 12px;
111 | 	font-family: ubuntu, helvetica, arial;
112 | 	overflow: hidden; /* this is important to prevent the whole page to bounce */
113 | }
114 | 
115 | #header {
116 | 	position: absolute;
117 | 	z-index: 2;
118 | 	top: 0;
119 | 	left: 0;
120 | 	width: 100%;
121 | 	height: 45px;
122 | 	line-height: 45px;
123 | 	background: #CD235C;
124 | 	padding: 0;
125 | 	color: #eee;
126 | 	font-size: 20px;
127 | 	text-align: center;
128 | 	font-weight: bold;
129 | }
130 | 
131 | #footer {
132 | 	position: absolute;
133 | 	z-index: 2;
134 | 	bottom: 0;
135 | 	left: 0;
136 | 	width: 100%;
137 | 	height: 48px;
138 | 	background: #444;
139 | 	padding: 0;
140 | 	border-top: 1px solid #444;
141 | }
142 | 
143 | #wrapper {
144 | 	position: absolute;
145 | 	z-index: 1;
146 | 	top: 45px;
147 | 	bottom: 48px;
148 | 	left: 0;
149 | 	width: 100%;
150 | 	background: #ccc;
151 | 	overflow: hidden;
152 | }
153 | 
154 | #scroller {
155 | 	position: absolute;
156 | 	z-index: 1;
157 | 	-webkit-tap-highlight-color: rgba(0,0,0,0);
158 | 	width: 100%;
159 | 	-webkit-transform: translateZ(0);
160 | 	-moz-transform: translateZ(0);
161 | 	-ms-transform: translateZ(0);
162 | 	-o-transform: translateZ(0);
163 | 	transform: translateZ(0);
164 | 	-webkit-touch-callout: none;
165 | 	-webkit-user-select: none;
166 | 	-moz-user-select: none;
167 | 	-ms-user-select: none;
168 | 	user-select: none;
169 | 	-webkit-text-size-adjust: none;
170 | 	-moz-text-size-adjust: none;
171 | 	-ms-text-size-adjust: none;
172 | 	-o-text-size-adjust: none;
173 | 	text-size-adjust: none;
174 | }
175 | 
176 | #scroller ul {
177 | 	list-style: none;
178 | 	padding: 0;
179 | 	margin: 0;
180 | 	width: 100%;
181 | 	text-align: left;
182 | 	position: relative;
183 | }
184 | 
185 | #scroller li {
186 | 	position: absolute;
187 | 	width: 100%;
188 | 	top: 0;
189 | 	left: 0;
190 | 	-webkit-transform: translateZ(0);
191 | 	-moz-transform: translateZ(0);
192 | 	-ms-transform: translateZ(0);
193 | 	-o-transform: translateZ(0);
194 | 	transform: translateZ(0);
195 | 	padding: 0 10px;
196 | 	height: 40px;
197 | 	line-height: 40px;
198 | 	border-bottom: 1px solid #ccc;
199 | 	border-top: 1px solid #fff;
200 | 	background-color: #fafafa;
201 | 	font-size: 16px;
202 | }
203 | 
204 | </style>
205 | </head>
206 | <body onload="loaded()">
207 | <div id="header">iScroll</div>
208 | 
209 | <div id="wrapper">
210 | 	<div id="scroller">
211 | 		<ul>
212 | 			<li class="row">Row 1</li>
213 | 			<li class="row">Row 2</li>
214 | 			<li class="row">Row 3</li>
215 | 			<li class="row">Row 4</li>
216 | 			<li class="row">Row 5</li>
217 | 			<li class="row">Row 6</li>
218 | 			<li class="row">Row 7</li>
219 | 			<li class="row">Row 8</li>
220 | 			<li class="row">Row 9</li>
221 | 			<li class="row">Row 10</li>
222 | 			<li class="row">Row 11</li>
223 | 			<li class="row">Row 12</li>
224 | 			<li class="row">Row 13</li>
225 | 			<li class="row">Row 14</li>
226 | 			<li class="row">Row 15</li>
227 | 
228 | 			<li class="row">Row 16</li>
229 | 			<li class="row">Row 17</li>
230 | 			<li class="row">Row 18</li>
231 | 			<li class="row">Row 19</li>
232 | 			<li class="row">Row 20</li>
233 | 			<li class="row">Row 21</li>
234 | 			<li class="row">Row 22</li>
235 | 			<li class="row">Row 23</li>
236 | 			<li class="row">Row 24</li>
237 | 			<li class="row">Row 25</li>
238 | 			<li class="row">Row 26</li>
239 | 			<li class="row">Row 27</li>
240 | 			<li class="row">Row 28</li>
241 | 			<li class="row">Row 29</li>
242 | 			<li class="row">Row 30</li>
243 | 		</ul>
244 | 	</div>
245 | </div>
246 | 
247 | <div id="footer"></div>
248 | 
249 | </body>
250 | </html>


--------------------------------------------------------------------------------
/demos/key-bindings/index.html:
--------------------------------------------------------------------------------
  1 | <!DOCTYPE html>
  2 | <html>
  3 | <head>
  4 | <meta charset="utf-8">
  5 | <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=0, minimum-scale=1.0, maximum-scale=1.0">
  6 | 
  7 | <title>iScroll demo: key bindings</title>
  8 | 
  9 | <script type="text/javascript" src="../../build/iscroll.js"></script>
 10 | <script type="text/javascript" src="../demoUtils.js"></script>
 11 | <script type="text/javascript">
 12 | 
 13 | var myScroll;
 14 | 
 15 | function loaded () {
 16 | 	myScroll = new IScroll('#wrapper', { keyBindings: true });
 17 | }
 18 | 
 19 | document.addEventListener('touchmove', function (e) { e.preventDefault(); }, isPassive() ? {
 20 | 	capture: false,
 21 | 	passive: false
 22 | } : false);
 23 | 
 24 | </script>
 25 | 
 26 | <style type="text/css">
 27 | * {
 28 | 	-webkit-box-sizing: border-box;
 29 | 	-moz-box-sizing: border-box;
 30 | 	box-sizing: border-box;
 31 | }
 32 | 
 33 | html {
 34 | 	-ms-touch-action: none;
 35 | }
 36 | 
 37 | body,ul,li {
 38 | 	padding: 0;
 39 | 	margin: 0;
 40 | 	border: 0;
 41 | }
 42 | 
 43 | body {
 44 | 	font-size: 12px;
 45 | 	font-family: ubuntu, helvetica, arial;
 46 | 	overflow: hidden; /* this is important to prevent the whole page to bounce */
 47 | }
 48 | 
 49 | #header {
 50 | 	position: absolute;
 51 | 	z-index: 2;
 52 | 	top: 0;
 53 | 	left: 0;
 54 | 	width: 100%;
 55 | 	height: 45px;
 56 | 	line-height: 45px;
 57 | 	background: #CD235C;
 58 | 	padding: 0;
 59 | 	color: #eee;
 60 | 	font-size: 20px;
 61 | 	text-align: center;
 62 | 	font-weight: bold;
 63 | }
 64 | 
 65 | #footer {
 66 | 	position: absolute;
 67 | 	z-index: 2;
 68 | 	bottom: 0;
 69 | 	left: 0;
 70 | 	width: 100%;
 71 | 	height: 48px;
 72 | 	background: #444;
 73 | 	padding: 0;
 74 | 	border-top: 1px solid #444;
 75 | }
 76 | 
 77 | #wrapper {
 78 | 	position: absolute;
 79 | 	z-index: 1;
 80 | 	top: 45px;
 81 | 	bottom: 48px;
 82 | 	left: 0;
 83 | 	width: 100%;
 84 | 	background: #ccc;
 85 | 	overflow: hidden;
 86 | }
 87 | 
 88 | #scroller {
 89 | 	position: absolute;
 90 | 	z-index: 1;
 91 | 	-webkit-tap-highlight-color: rgba(0,0,0,0);
 92 | 	width: 100%;
 93 | 	-webkit-transform: translateZ(0);
 94 | 	-moz-transform: translateZ(0);
 95 | 	-ms-transform: translateZ(0);
 96 | 	-o-transform: translateZ(0);
 97 | 	transform: translateZ(0);
 98 | 	-webkit-touch-callout: none;
 99 | 	-webkit-user-select: none;
100 | 	-moz-user-select: none;
101 | 	-ms-user-select: none;
102 | 	user-select: none;
103 | 	-webkit-text-size-adjust: none;
104 | 	-moz-text-size-adjust: none;
105 | 	-ms-text-size-adjust: none;
106 | 	-o-text-size-adjust: none;
107 | 	text-size-adjust: none;
108 | }
109 | 
110 | #scroller ul {
111 | 	list-style: none;
112 | 	padding: 0;
113 | 	margin: 0;
114 | 	width: 100%;
115 | 	text-align: left;
116 | }
117 | 
118 | #scroller li {
119 | 	padding: 0 10px;
120 | 	height: 40px;
121 | 	line-height: 40px;
122 | 	border-bottom: 1px solid #ccc;
123 | 	border-top: 1px solid #fff;
124 | 	background-color: #fafafa;
125 | 	font-size: 14px;
126 | }
127 | 
128 | </style>
129 | </head>
130 | <body onload="loaded()">
131 | <div id="header">iScroll</div>
132 | 
133 | <div id="wrapper">
134 | 	<div id="scroller">
135 | 		<ul>
136 | 			<li>Pretty row 1</li>
137 | 			<li>Pretty row 2</li>
138 | 			<li>Pretty row 3</li>
139 | 			<li>Pretty row 4</li>
140 | 			<li>Pretty row 5</li>
141 | 			<li>Pretty row 6</li>
142 | 			<li>Pretty row 7</li>
143 | 			<li>Pretty row 8</li>
144 | 			<li>Pretty row 9</li>
145 | 			<li>Pretty row 10</li>
146 | 			<li>Pretty row 11</li>
147 | 			<li>Pretty row 12</li>
148 | 			<li>Pretty row 13</li>
149 | 			<li>Pretty row 14</li>
150 | 			<li>Pretty row 15</li>
151 | 			<li>Pretty row 16</li>
152 | 			<li>Pretty row 17</li>
153 | 			<li>Pretty row 18</li>
154 | 			<li>Pretty row 19</li>
155 | 			<li>Pretty row 20</li>
156 | 			<li>Pretty row 21</li>
157 | 			<li>Pretty row 22</li>
158 | 			<li>Pretty row 23</li>
159 | 			<li>Pretty row 24</li>
160 | 			<li>Pretty row 25</li>
161 | 			<li>Pretty row 26</li>
162 | 			<li>Pretty row 27</li>
163 | 			<li>Pretty row 28</li>
164 | 			<li>Pretty row 29</li>
165 | 			<li>Pretty row 30</li>
166 | 			<li>Pretty row 31</li>
167 | 			<li>Pretty row 32</li>
168 | 			<li>Pretty row 33</li>
169 | 			<li>Pretty row 34</li>
170 | 			<li>Pretty row 35</li>
171 | 			<li>Pretty row 36</li>
172 | 			<li>Pretty row 37</li>
173 | 			<li>Pretty row 38</li>
174 | 			<li>Pretty row 39</li>
175 | 			<li>Pretty row 40</li>
176 | 			<li>Pretty row 41</li>
177 | 			<li>Pretty row 42</li>
178 | 			<li>Pretty row 43</li>
179 | 			<li>Pretty row 44</li>
180 | 			<li>Pretty row 45</li>
181 | 			<li>Pretty row 46</li>
182 | 			<li>Pretty row 47</li>
183 | 			<li>Pretty row 48</li>
184 | 			<li>Pretty row 49</li>
185 | 			<li>Pretty row 50</li>
186 | 		</ul>
187 | 	</div>
188 | </div>
189 | 
190 | <div id="footer"></div>
191 | 
192 | </body>
193 | </html>


--------------------------------------------------------------------------------
/demos/minimap/ermine.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cubiq/iscroll/60ed6f8029b2e097a87399a2b3c688afd596980f/demos/minimap/ermine.jpg


--------------------------------------------------------------------------------
/demos/minimap/index.html:
--------------------------------------------------------------------------------
  1 | <!DOCTYPE html>
  2 | <html>
  3 | <head>
  4 | <meta charset="utf-8">
  5 | <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=0, minimum-scale=1.0, maximum-scale=1.0">
  6 | 
  7 | <title>iScroll demo: minimap</title>
  8 | 
  9 | <script type="text/javascript" src="../../build/iscroll.js"></script>
 10 | <!--<script type="text/javascript" src="../demoUtils.js"></script>-->
 11 | <script type="text/javascript">
 12 | 
 13 | var myScroll;
 14 | 
 15 | function loaded () {
 16 | 	myScroll = new IScroll('#wrapper', {
 17 | 		startX: -359,
 18 | 		startY: -85,
 19 | 		scrollY: true,
 20 | 		scrollX: true,
 21 | 		freeScroll: true,
 22 | 		mouseWheel: true,
 23 | 		indicators: {
 24 | 			el: document.getElementById('minimap'),
 25 | 			interactive: true
 26 | 		}
 27 | 	});
 28 | }
 29 | 
 30 | // document.addEventListener('touchmove', function (e) { e.preventDefault(); }, isPassive() ? {
 31 | // 	capture: false,
 32 | // 	passive: false
 33 | // } : false);
 34 | 
 35 | </script>
 36 | 
 37 | <style type="text/css">
 38 | * {
 39 | 	-webkit-box-sizing: border-box;
 40 | 	-moz-box-sizing: border-box;
 41 | 	box-sizing: border-box;
 42 | }
 43 | 
 44 | html {
 45 | 	-ms-touch-action: none;
 46 | }
 47 | 
 48 | body,ul,li {
 49 | 	padding: 0;
 50 | 	margin: 0;
 51 | 	border: 0;
 52 | }
 53 | 
 54 | body {
 55 | 	font-size: 12px;
 56 | 	font-family: ubuntu, helvetica, arial;
 57 | 	overflow: hidden; /* this is important to prevent the whole page to bounce */
 58 | }
 59 | 
 60 | #header {
 61 | 	position: absolute;
 62 | 	z-index: 2;
 63 | 	top: 0;
 64 | 	left: 0;
 65 | 	width: 100%;
 66 | 	height: 45px;
 67 | 	line-height: 45px;
 68 | 	background: #CD235C;
 69 | 	padding: 0;
 70 | 	color: #eee;
 71 | 	font-size: 20px;
 72 | 	text-align: center;
 73 | 	font-weight: bold;
 74 | }
 75 | 
 76 | #footer {
 77 | 	position: absolute;
 78 | 	z-index: 2;
 79 | 	bottom: 0;
 80 | 	left: 0;
 81 | 	width: 100%;
 82 | 	height: 48px;
 83 | 	background: #444;
 84 | 	padding: 0;
 85 | 	border-top: 1px solid #444;
 86 | }
 87 | 
 88 | #wrapper {
 89 | 	position: absolute;
 90 | 	z-index: 1;
 91 | 	width: 235px;
 92 | 	height: 321px;
 93 | 	top: 0;
 94 | 	left: 0;
 95 | 	background: #555;
 96 | 	overflow: hidden;
 97 | }
 98 | 
 99 | #scroller {
100 | 	position: absolute;
101 | 	z-index: 1;
102 | 	width: 797px;
103 | 	height: 1087px;
104 | 	background: url(ermine.jpg);
105 | 	-webkit-tap-highlight-color: rgba(0,0,0,0);
106 | 	-webkit-transform: translateZ(0);
107 | 	-moz-transform: translateZ(0);
108 | 	-ms-transform: translateZ(0);
109 | 	-o-transform: translateZ(0);
110 | 	transform: translateZ(0);
111 | 	-webkit-touch-callout: none;
112 | 	-webkit-user-select: none;
113 | 	-moz-user-select: none;
114 | 	-ms-user-select: none;
115 | 	user-select: none;
116 | 	-webkit-text-size-adjust: none;
117 | 	-moz-text-size-adjust: none;
118 | 	-ms-text-size-adjust: none;
119 | 	-o-text-size-adjust: none;
120 | 	text-size-adjust: none;
121 | }
122 | 
123 | #minimap {
124 | 	position: absolute;
125 | 	z-index: 1;
126 | 	width: 235px;
127 | 	height: 321px;
128 | 	background: url(ermine.jpg);
129 | 	background-size: 235px 321px;
130 | 	top: 0px;
131 | 	left: 245px;
132 | }
133 | 
134 | #minimap-indicator {
135 | 	position: absolute;
136 | 	z-index: 1;
137 | 	border: 1px solid #fe0;
138 | 	box-shadow: 0 0 5px #000;
139 | 	background: rgba(255,255,255,0.15);
140 | 	-webkit-transform: translateZ(0);
141 | 	-moz-transform: translateZ(0);
142 | 	-ms-transform: translateZ(0);
143 | 	-o-transform: translateZ(0);
144 | 	transform: translateZ(0);
145 | }
146 | 
147 | #bookmarks {
148 | 	position: absolute;
149 | 	left: 520px;
150 | 	font-size: 1.4em;
151 | }
152 | 
153 | #bookmarks li {
154 | 	margin: 5px 0;
155 | }
156 | 
157 | </style>
158 | </head>
159 | <body onload="loaded()">
160 | 
161 | <div id="wrapper">
162 | 	<div id="scroller"></div>
163 | </div>
164 | 
165 | <div id="minimap">
166 | 	<div id="minimap-indicator"></div>
167 | </div>
168 | 
169 | <ul id="bookmarks">
170 | 	<li><a href="javascript:myScroll.scrollTo(-359, -85, 400, IScroll.utils.ease.back)">Face</a></li>
171 | 	<li><a href="javascript:myScroll.scrollTo(-288, -342, 400, IScroll.utils.ease.back)">Necklace</a></li>
172 | 	<li><a href="javascript:myScroll.scrollTo(-264, -658, 400, IScroll.utils.ease.back)">Hand</a></li>
173 | 	<li><a href="javascript:myScroll.scrollTo(-383, -539, 400, IScroll.utils.ease.back)">Ermine</a></li>
174 | </ul>
175 | 
176 | </body>
177 | </html>


--------------------------------------------------------------------------------
/demos/no-transition/index.html:
--------------------------------------------------------------------------------
  1 | <!DOCTYPE html>
  2 | <html>
  3 | <head>
  4 | <meta charset="utf-8">
  5 | <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=0, minimum-scale=1.0, maximum-scale=1.0">
  6 | 
  7 | <title>iScroll demo: No transition</title>
  8 | 
  9 | <script type="text/javascript" src="../../build/iscroll.js"></script>
 10 | <script type="text/javascript" src="../demoUtils.js"></script>
 11 | <script type="text/javascript">
 12 | 
 13 | var myScroll;
 14 | 
 15 | function loaded () {
 16 | 	myScroll = new IScroll('#wrapper', { useTransition: false });
 17 | }
 18 | 
 19 | document.addEventListener('touchmove', function (e) { e.preventDefault(); }, isPassive() ? {
 20 | 	capture: false,
 21 | 	passive: false
 22 | } : false);
 23 | 
 24 | </script>
 25 | 
 26 | <style type="text/css">
 27 | * {
 28 | 	-webkit-box-sizing: border-box;
 29 | 	-moz-box-sizing: border-box;
 30 | 	box-sizing: border-box;
 31 | }
 32 | 
 33 | html {
 34 | 	-ms-touch-action: none;
 35 | }
 36 | 
 37 | body,ul,li {
 38 | 	padding: 0;
 39 | 	margin: 0;
 40 | 	border: 0;
 41 | }
 42 | 
 43 | body {
 44 | 	font-size: 12px;
 45 | 	font-family: ubuntu, helvetica, arial;
 46 | 	overflow: hidden; /* this is important to prevent the whole page to bounce */
 47 | }
 48 | 
 49 | #header {
 50 | 	position: absolute;
 51 | 	z-index: 2;
 52 | 	top: 0;
 53 | 	left: 0;
 54 | 	width: 100%;
 55 | 	height: 45px;
 56 | 	line-height: 45px;
 57 | 	background: #CD235C;
 58 | 	padding: 0;
 59 | 	color: #eee;
 60 | 	font-size: 20px;
 61 | 	text-align: center;
 62 | 	font-weight: bold;
 63 | }
 64 | 
 65 | #footer {
 66 | 	position: absolute;
 67 | 	z-index: 2;
 68 | 	bottom: 0;
 69 | 	left: 0;
 70 | 	width: 100%;
 71 | 	height: 48px;
 72 | 	background: #444;
 73 | 	padding: 0;
 74 | 	border-top: 1px solid #444;
 75 | }
 76 | 
 77 | #wrapper {
 78 | 	position: absolute;
 79 | 	z-index: 1;
 80 | 	top: 45px;
 81 | 	bottom: 48px;
 82 | 	left: 0;
 83 | 	width: 100%;
 84 | 	background: #ccc;
 85 | 	overflow: hidden;
 86 | 	-webkit-touch-callout: none;
 87 | 	-webkit-user-select: none;
 88 | 	-moz-user-select: none;
 89 | 	-ms-user-select: none;
 90 | 	user-select: none;
 91 | 	-webkit-text-size-adjust: none;
 92 | 	-moz-text-size-adjust: none;
 93 | 	-ms-text-size-adjust: none;
 94 | 	-o-text-size-adjust: none;
 95 | 	text-size-adjust: none;
 96 | }
 97 | 
 98 | #scroller {
 99 | 	position: absolute;
100 | 	z-index: 1;
101 | 	-webkit-tap-highlight-color: rgba(0,0,0,0);
102 | 	width: 100%;
103 | 	-webkit-transform: translateZ(0);
104 | 	-moz-transform: translateZ(0);
105 | 	-ms-transform: translateZ(0);
106 | 	-o-transform: translateZ(0);
107 | 	transform: translateZ(0);
108 | }
109 | 
110 | #scroller ul {
111 | 	list-style: none;
112 | 	padding: 0;
113 | 	margin: 0;
114 | 	width: 100%;
115 | 	text-align: left;
116 | }
117 | 
118 | #scroller li {
119 | 	padding: 0 10px;
120 | 	height: 40px;
121 | 	line-height: 40px;
122 | 	border-bottom: 1px solid #ccc;
123 | 	border-top: 1px solid #fff;
124 | 	background-color: #fafafa;
125 | 	font-size: 14px;
126 | }
127 | 
128 | </style>
129 | </head>
130 | <body onload="loaded()">
131 | <div id="header">iScroll</div>
132 | 
133 | <div id="wrapper">
134 | 	<div id="scroller">
135 | 		<ul>
136 | 			<li>Pretty row 1</li>
137 | 			<li>Pretty row 2</li>
138 | 			<li>Pretty row 3</li>
139 | 			<li>Pretty row 4</li>
140 | 			<li>Pretty row 5</li>
141 | 			<li>Pretty row 6</li>
142 | 			<li>Pretty row 7</li>
143 | 			<li>Pretty row 8</li>
144 | 			<li>Pretty row 9</li>
145 | 			<li>Pretty row 10</li>
146 | 			<li>Pretty row 11</li>
147 | 			<li>Pretty row 12</li>
148 | 			<li>Pretty row 13</li>
149 | 			<li>Pretty row 14</li>
150 | 			<li>Pretty row 15</li>
151 | 			<li>Pretty row 16</li>
152 | 			<li>Pretty row 17</li>
153 | 			<li>Pretty row 18</li>
154 | 			<li>Pretty row 19</li>
155 | 			<li>Pretty row 20</li>
156 | 			<li>Pretty row 21</li>
157 | 			<li>Pretty row 22</li>
158 | 			<li>Pretty row 23</li>
159 | 			<li>Pretty row 24</li>
160 | 			<li>Pretty row 25</li>
161 | 			<li>Pretty row 26</li>
162 | 			<li>Pretty row 27</li>
163 | 			<li>Pretty row 28</li>
164 | 			<li>Pretty row 29</li>
165 | 			<li>Pretty row 30</li>
166 | 			<li>Pretty row 31</li>
167 | 			<li>Pretty row 32</li>
168 | 			<li>Pretty row 33</li>
169 | 			<li>Pretty row 34</li>
170 | 			<li>Pretty row 35</li>
171 | 			<li>Pretty row 36</li>
172 | 			<li>Pretty row 37</li>
173 | 			<li>Pretty row 38</li>
174 | 			<li>Pretty row 39</li>
175 | 			<li>Pretty row 40</li>
176 | 			<li>Pretty row 41</li>
177 | 			<li>Pretty row 42</li>
178 | 			<li>Pretty row 43</li>
179 | 			<li>Pretty row 44</li>
180 | 			<li>Pretty row 45</li>
181 | 			<li>Pretty row 46</li>
182 | 			<li>Pretty row 47</li>
183 | 			<li>Pretty row 48</li>
184 | 			<li>Pretty row 49</li>
185 | 			<li>Pretty row 50</li>
186 | 		</ul>
187 | 	</div>
188 | </div>
189 | 
190 | <div id="footer"></div>
191 | 
192 | </body>
193 | </html>


--------------------------------------------------------------------------------
/demos/parallax/galaxies1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cubiq/iscroll/60ed6f8029b2e097a87399a2b3c688afd596980f/demos/parallax/galaxies1.png


--------------------------------------------------------------------------------
/demos/parallax/galaxies2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cubiq/iscroll/60ed6f8029b2e097a87399a2b3c688afd596980f/demos/parallax/galaxies2.png


--------------------------------------------------------------------------------
/demos/parallax/index.html:
--------------------------------------------------------------------------------
  1 | <!DOCTYPE html>
  2 | <html>
  3 | <head>
  4 | <meta charset="utf-8">
  5 | <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=0, minimum-scale=1.0, maximum-scale=1.0">
  6 | 
  7 | <title>iScroll demo: starfield</title>
  8 | 
  9 | <script type="text/javascript" src="../../build/iscroll.js"></script>
 10 | <script type="text/javascript" src="../demoUtils.js"></script>
 11 | <script type="text/javascript">
 12 | 
 13 | var myScroll;
 14 | 
 15 | function loaded () {
 16 | 	myScroll = new IScroll('#wrapper', {
 17 | 		mouseWheel: true,
 18 | 		indicators: [{
 19 | 			el: document.getElementById('starfield1'),
 20 | 			resize: false,
 21 | 			ignoreBoundaries: true,
 22 | 			speedRatioY: 0.4
 23 | 		}, {
 24 | 			el: document.getElementById('starfield2'),
 25 | 			resize: false,
 26 | 			ignoreBoundaries: true,
 27 | 			speedRatioY: 0.2
 28 | 		}]
 29 | 	});
 30 | }
 31 | 
 32 | document.addEventListener('touchmove', function (e) { e.preventDefault(); }, isPassive() ? {
 33 | 	capture: false,
 34 | 	passive: false
 35 | } : false);
 36 | 
 37 | </script>
 38 | 
 39 | <style type="text/css">
 40 | * {
 41 | 	-webkit-box-sizing: border-box;
 42 | 	-moz-box-sizing: border-box;
 43 | 	box-sizing: border-box;
 44 | }
 45 | 
 46 | html {
 47 | 	-ms-touch-action: none;
 48 | }
 49 | 
 50 | body,ul,li {
 51 | 	padding: 0;
 52 | 	margin: 0;
 53 | 	border: 0;
 54 | }
 55 | 
 56 | body {
 57 | 	font-size: 12px;
 58 | 	font-family: ubuntu, helvetica, arial;
 59 | 	overflow: hidden; /* this is important to prevent the whole page to bounce */
 60 | 	background: #000;
 61 | }
 62 | 
 63 | #wrapper {
 64 | 	position: absolute;
 65 | 	z-index: 3;
 66 | 	width: 100%;
 67 | 	top: 0;
 68 | 	bottom: 0;
 69 | 	left: 0;
 70 | 	overflow: hidden;
 71 | }
 72 | 
 73 | #scroller {
 74 | 	position: absolute;
 75 | 	z-index: 3;
 76 | 	width: 100%;
 77 | 	height: 4000px;
 78 | 	overflow: hidden;
 79 | 	-webkit-tap-highlight-color: rgba(0,0,0,0);
 80 | 	-webkit-transform: translateZ(0);
 81 | 	-moz-transform: translateZ(0);
 82 | 	-ms-transform: translateZ(0);
 83 | 	-o-transform: translateZ(0);
 84 | 	transform: translateZ(0);
 85 | 	-webkit-touch-callout: none;
 86 | 	-webkit-user-select: none;
 87 | 	-moz-user-select: none;
 88 | 	-ms-user-select: none;
 89 | 	user-select: none;
 90 | 	-webkit-text-size-adjust: none;
 91 | 	-moz-text-size-adjust: none;
 92 | 	-ms-text-size-adjust: none;
 93 | 	-o-text-size-adjust: none;
 94 | 	text-size-adjust: none;
 95 | 	background: url(galaxies1.png);
 96 | }
 97 | 
 98 | .starfield {
 99 | 	position: absolute;
100 | 	width: 100%;
101 | 	top: 0;
102 | 	left: 0;
103 | 	bottom: 0;
104 | 	overflow: hidden;
105 | }
106 | 
107 | .starfield div {
108 | 	position: absolute;
109 | 	width: 100%;
110 | 	overflow: hidden;
111 | 	-webkit-transform: translateZ(0);
112 | 	-moz-transform: translateZ(0);
113 | 	-ms-transform: translateZ(0);
114 | 	-o-transform: translateZ(0);
115 | 	transform: translateZ(0);
116 | }
117 | 
118 | #starfield1 {
119 | 	z-index: 2;
120 | }
121 | 
122 | #stars1 {
123 | 	z-index: 2;
124 | 	height: 3000px;
125 | 	background: url(galaxies2.png);
126 | }
127 | 
128 | #starfield2 {
129 | 	z-index: 1;
130 | }
131 | 
132 | #stars2 {
133 | 	z-index: 1;
134 | 	height: 2000px;
135 | 	background: url(stars.jpg);
136 | }
137 | 
138 | </style>
139 | </head>
140 | <body onload="loaded()">
141 | 
142 | <div id="wrapper">
143 | 	<div id="scroller"></div>
144 | </div>
145 | 
146 | <div class="starfield" id="starfield1">
147 | 	<div id="stars1"></div>
148 | </div>
149 | 
150 | <div class="starfield" id="starfield2">
151 | 	<div id="stars2"></div>
152 | </div>
153 | 
154 | </body>
155 | </html>


--------------------------------------------------------------------------------
/demos/parallax/stars.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cubiq/iscroll/60ed6f8029b2e097a87399a2b3c688afd596980f/demos/parallax/stars.jpg


--------------------------------------------------------------------------------
/demos/probe/index.html:
--------------------------------------------------------------------------------
  1 | <!DOCTYPE html>
  2 | <html>
  3 | <head>
  4 | <meta charset="utf-8">
  5 | <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=0, minimum-scale=1.0, maximum-scale=1.0">
  6 | 
  7 | <title>iScroll demo: probe</title>
  8 | 
  9 | <script type="text/javascript" src="../../build/iscroll-probe.js"></script>
 10 | <script type="text/javascript" src="../demoUtils.js"></script>
 11 | <script type="text/javascript">
 12 | 
 13 | var myScroll;
 14 | var position;
 15 | 
 16 | function updatePosition () {
 17 | 	position.innerHTML = this.y>>0;
 18 | }
 19 | 
 20 | function loaded () {
 21 | 	position = document.getElementById('position');
 22 | 
 23 | 	myScroll = new IScroll('#wrapper', { probeType: 3, mouseWheel: true });
 24 | 
 25 | 	myScroll.on('scroll', updatePosition);
 26 | 	myScroll.on('scrollEnd', updatePosition);
 27 | }
 28 | 
 29 | document.addEventListener('touchmove', function (e) { e.preventDefault(); }, isPassive() ? {
 30 | 	capture: false,
 31 | 	passive: false
 32 | } : false);
 33 | 
 34 | </script>
 35 | 
 36 | <style type="text/css">
 37 | * {
 38 | 	-webkit-box-sizing: border-box;
 39 | 	-moz-box-sizing: border-box;
 40 | 	box-sizing: border-box;
 41 | }
 42 | 
 43 | html {
 44 | 	-ms-touch-action: none;
 45 | }
 46 | 
 47 | body,ul,li {
 48 | 	padding: 0;
 49 | 	margin: 0;
 50 | 	border: 0;
 51 | }
 52 | 
 53 | body {
 54 | 	font-size: 12px;
 55 | 	font-family: ubuntu, helvetica, arial;
 56 | 	overflow: hidden; /* this is important to prevent the whole page to bounce */
 57 | }
 58 | 
 59 | #wrapper {
 60 | 	position: absolute;
 61 | 	z-index: 1;
 62 | 	top: 0;
 63 | 	bottom: 0;
 64 | 	left: 0;
 65 | 	width: 50%;
 66 | 	background: #ccc;
 67 | 	overflow: hidden;
 68 | }
 69 | 
 70 | #scroller {
 71 | 	position: absolute;
 72 | 	z-index: 1;
 73 | 	-webkit-tap-highlight-color: rgba(0,0,0,0);
 74 | 	width: 100%;
 75 | 	-webkit-transform: translateZ(0);
 76 | 	-moz-transform: translateZ(0);
 77 | 	-ms-transform: translateZ(0);
 78 | 	-o-transform: translateZ(0);
 79 | 	transform: translateZ(0);
 80 | 	-webkit-touch-callout: none;
 81 | 	-webkit-user-select: none;
 82 | 	-moz-user-select: none;
 83 | 	-ms-user-select: none;
 84 | 	user-select: none;
 85 | 	-webkit-text-size-adjust: none;
 86 | 	-moz-text-size-adjust: none;
 87 | 	-ms-text-size-adjust: none;
 88 | 	-o-text-size-adjust: none;
 89 | 	text-size-adjust: none;
 90 | }
 91 | 
 92 | #scroller ul {
 93 | 	list-style: none;
 94 | 	padding: 0;
 95 | 	margin: 0;
 96 | 	width: 100%;
 97 | 	text-align: left;
 98 | }
 99 | 
100 | #scroller li {
101 | 	padding: 0 10px;
102 | 	height: 40px;
103 | 	line-height: 40px;
104 | 	border-bottom: 1px solid #ccc;
105 | 	border-top: 1px solid #fff;
106 | 	background-color: #fafafa;
107 | 	font-size: 14px;
108 | }
109 | 
110 | #monitor {
111 | 	position: absolute;
112 | 	left: 51%;
113 | }
114 | 
115 | </style>
116 | </head>
117 | <body onload="loaded()">
118 | 
119 | <div id="monitor">Y position: <strong id="position">0</strong></div>
120 | 
121 | <div id="wrapper">
122 | 	<div id="scroller">
123 | 		<ul>
124 | 			<li>Pretty row 1</li>
125 | 			<li>Pretty row 2</li>
126 | 			<li>Pretty row 3</li>
127 | 			<li>Pretty row 4</li>
128 | 			<li>Pretty row 5</li>
129 | 			<li>Pretty row 6</li>
130 | 			<li>Pretty row 7</li>
131 | 			<li>Pretty row 8</li>
132 | 			<li>Pretty row 9</li>
133 | 			<li>Pretty row 10</li>
134 | 			<li>Pretty row 11</li>
135 | 			<li>Pretty row 12</li>
136 | 			<li>Pretty row 13</li>
137 | 			<li>Pretty row 14</li>
138 | 			<li>Pretty row 15</li>
139 | 			<li>Pretty row 16</li>
140 | 			<li>Pretty row 17</li>
141 | 			<li>Pretty row 18</li>
142 | 			<li>Pretty row 19</li>
143 | 			<li>Pretty row 20</li>
144 | 			<li>Pretty row 21</li>
145 | 			<li>Pretty row 22</li>
146 | 			<li>Pretty row 23</li>
147 | 			<li>Pretty row 24</li>
148 | 			<li>Pretty row 25</li>
149 | 			<li>Pretty row 26</li>
150 | 			<li>Pretty row 27</li>
151 | 			<li>Pretty row 28</li>
152 | 			<li>Pretty row 29</li>
153 | 			<li>Pretty row 30</li>
154 | 			<li>Pretty row 31</li>
155 | 			<li>Pretty row 32</li>
156 | 			<li>Pretty row 33</li>
157 | 			<li>Pretty row 34</li>
158 | 			<li>Pretty row 35</li>
159 | 			<li>Pretty row 36</li>
160 | 			<li>Pretty row 37</li>
161 | 			<li>Pretty row 38</li>
162 | 			<li>Pretty row 39</li>
163 | 			<li>Pretty row 40</li>
164 | 			<li>Pretty row 41</li>
165 | 			<li>Pretty row 42</li>
166 | 			<li>Pretty row 43</li>
167 | 			<li>Pretty row 44</li>
168 | 			<li>Pretty row 45</li>
169 | 			<li>Pretty row 46</li>
170 | 			<li>Pretty row 47</li>
171 | 			<li>Pretty row 48</li>
172 | 			<li>Pretty row 49</li>
173 | 			<li>Pretty row 50</li>
174 | 		</ul>
175 | 	</div>
176 | </div>
177 | 
178 | </body>
179 | </html>


--------------------------------------------------------------------------------
/demos/scroll-to-element/index.html:
--------------------------------------------------------------------------------
  1 | <!DOCTYPE html>
  2 | <html>
  3 | <head>
  4 | <meta charset="utf-8">
  5 | <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=0, minimum-scale=1.0, maximum-scale=1.0">
  6 | 
  7 | <title>iScroll demo: scroll to element</title>
  8 | 
  9 | <script type="text/javascript" src="../../build/iscroll.js"></script>
 10 | <script type="text/javascript" src="../demoUtils.js"></script>
 11 | <script type="text/javascript">
 12 | 
 13 | var myScroll;
 14 | 
 15 | function loaded () {
 16 | 	myScroll = new IScroll('#wrapper', { mouseWheel: true, click: true });
 17 | }
 18 | 
 19 | document.addEventListener('touchmove', function (e) { e.preventDefault(); }, isPassive() ? {
 20 | 	capture: false,
 21 | 	passive: false
 22 | } : false);
 23 | 
 24 | </script>
 25 | 
 26 | <style type="text/css">
 27 | * {
 28 | 	-webkit-box-sizing: border-box;
 29 | 	-moz-box-sizing: border-box;
 30 | 	box-sizing: border-box;
 31 | }
 32 | 
 33 | html {
 34 | 	-ms-touch-action: none;
 35 | }
 36 | 
 37 | body,ul,li {
 38 | 	padding: 0;
 39 | 	margin: 0;
 40 | 	border: 0;
 41 | }
 42 | 
 43 | body {
 44 | 	font-size: 12px;
 45 | 	font-family: ubuntu, helvetica, arial;
 46 | 	overflow: hidden; /* this is important to prevent the whole page to bounce */
 47 | }
 48 | 
 49 | #header {
 50 | 	position: absolute;
 51 | 	z-index: 2;
 52 | 	top: 0;
 53 | 	left: 0;
 54 | 	width: 100%;
 55 | 	height: 45px;
 56 | 	line-height: 45px;
 57 | 	background: #CD235C;
 58 | 	padding: 0;
 59 | 	color: #eee;
 60 | 	font-size: 20px;
 61 | 	text-align: center;
 62 | 	font-weight: bold;
 63 | }
 64 | 
 65 | #footer {
 66 | 	position: absolute;
 67 | 	z-index: 2;
 68 | 	bottom: 0;
 69 | 	left: 0;
 70 | 	width: 100%;
 71 | 	height: 48px;
 72 | 	background: #444;
 73 | 	padding: 0;
 74 | 	border-top: 1px solid #444;
 75 | }
 76 | 
 77 | #wrapper {
 78 | 	position: absolute;
 79 | 	z-index: 1;
 80 | 	top: 45px;
 81 | 	bottom: 48px;
 82 | 	left: 0;
 83 | 	width: 100%;
 84 | 	background: #ccc;
 85 | 	overflow: hidden;
 86 | }
 87 | 
 88 | #scroller {
 89 | 	position: absolute;
 90 | 	z-index: 1;
 91 | 	-webkit-tap-highlight-color: rgba(0,0,0,0);
 92 | 	width: 100%;
 93 | 	-webkit-transform: translateZ(0);
 94 | 	-moz-transform: translateZ(0);
 95 | 	-ms-transform: translateZ(0);
 96 | 	-o-transform: translateZ(0);
 97 | 	transform: translateZ(0);
 98 | 	-webkit-touch-callout: none;
 99 | 	-webkit-user-select: none;
100 | 	-moz-user-select: none;
101 | 	-ms-user-select: none;
102 | 	user-select: none;
103 | 	-webkit-text-size-adjust: none;
104 | 	-moz-text-size-adjust: none;
105 | 	-ms-text-size-adjust: none;
106 | 	-o-text-size-adjust: none;
107 | 	text-size-adjust: none;
108 | }
109 | 
110 | #scroller ul {
111 | 	list-style: none;
112 | 	padding: 0;
113 | 	margin: 0;
114 | 	width: 100%;
115 | 	text-align: left;
116 | }
117 | 
118 | #scroller li {
119 | 	padding: 0 10px;
120 | 	height: 40px;
121 | 	line-height: 40px;
122 | 	border-bottom: 1px solid #ccc;
123 | 	border-top: 1px solid #fff;
124 | 	background-color: #fafafa;
125 | 	font-size: 14px;
126 | }
127 | 
128 | </style>
129 | </head>
130 | <body onload="loaded()">
131 | <div id="header">iScroll</div>
132 | 
133 | <div id="wrapper">
134 | 	<div id="scroller">
135 | 		<ul>
136 | 			<li><a href="javascript:myScroll.scrollToElement(document.querySelector('#scroller li:nth-child(10)'))">Scroll to element 10</a></li>
137 | 			<li>Pretty row 2</li>
138 | 			<li>Pretty row 3</li>
139 | 			<li>Pretty row 4</li>
140 | 			<li>Pretty row 5</li>
141 | 			<li>Pretty row 6</li>
142 | 			<li>Pretty row 7</li>
143 | 			<li>Pretty row 8</li>
144 | 			<li>Pretty row 9</li>
145 | 			<li><a href="javascript:myScroll.scrollToElement(document.querySelector('#scroller li:nth-child(25)'), null, null, true)">Center element 25 to screen</a></li>
146 | 			<li>Pretty row 11</li>
147 | 			<li>Pretty row 12</li>
148 | 			<li>Pretty row 13</li>
149 | 			<li>Pretty row 14</li>
150 | 			<li>Pretty row 15</li>
151 | 			<li>Pretty row 16</li>
152 | 			<li>Pretty row 17</li>
153 | 			<li>Pretty row 18</li>
154 | 			<li>Pretty row 19</li>
155 | 			<li>Pretty row 20</li>
156 | 			<li>Pretty row 21</li>
157 | 			<li>Pretty row 22</li>
158 | 			<li>Pretty row 23</li>
159 | 			<li>Pretty row 24</li>
160 | 			<li><a href="javascript:myScroll.scrollToElement(document.querySelector('#scroller li:nth-child(50)'), 1200, null, null, IScroll.utils.ease.elastic)">Scroll to the last element with elastic easing</a></li>
161 | 			<li>Pretty row 26</li>
162 | 			<li>Pretty row 27</li>
163 | 			<li>Pretty row 28</li>
164 | 			<li>Pretty row 29</li>
165 | 			<li>Pretty row 30</li>
166 | 			<li>Pretty row 31</li>
167 | 			<li>Pretty row 32</li>
168 | 			<li>Pretty row 33</li>
169 | 			<li>Pretty row 34</li>
170 | 			<li>Pretty row 35</li>
171 | 			<li>Pretty row 36</li>
172 | 			<li>Pretty row 37</li>
173 | 			<li>Pretty row 38</li>
174 | 			<li>Pretty row 39</li>
175 | 			<li>Pretty row 40</li>
176 | 			<li>Pretty row 41</li>
177 | 			<li>Pretty row 42</li>
178 | 			<li>Pretty row 43</li>
179 | 			<li>Pretty row 44</li>
180 | 			<li>Pretty row 45</li>
181 | 			<li>Pretty row 46</li>
182 | 			<li>Pretty row 47</li>
183 | 			<li>Pretty row 48</li>
184 | 			<li>Pretty row 49</li>
185 | 			<li>Pretty row 50</li>
186 | 		</ul>
187 | 	</div>
188 | </div>
189 | 
190 | <div id="footer"></div>
191 | 
192 | </body>
193 | </html>


--------------------------------------------------------------------------------
/demos/scrollbars/index.html:
--------------------------------------------------------------------------------
  1 | <!DOCTYPE html>
  2 | <html>
  3 | <head>
  4 | <meta charset="utf-8">
  5 | <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=0, minimum-scale=1.0, maximum-scale=1.0">
  6 | 
  7 | <title>iScroll demo: scrollbars</title>
  8 | 
  9 | <script type="text/javascript" src="../../build/iscroll.js"></script>
 10 | <script type="text/javascript" src="../demoUtils.js"></script>
 11 | <script type="text/javascript">
 12 | 
 13 | var myScroll;
 14 | 
 15 | function loaded () {
 16 | 	myScroll = new IScroll('#wrapper', {
 17 | 		scrollbars: true,
 18 | 		mouseWheel: true,
 19 | 		interactiveScrollbars: true,
 20 | 		shrinkScrollbars: 'scale',
 21 | 		fadeScrollbars: true
 22 | 	});
 23 | }
 24 | 
 25 | document.addEventListener('touchmove', function (e) { e.preventDefault(); }, isPassive() ? {
 26 | 	capture: false,
 27 | 	passive: false
 28 | } : false);
 29 | 
 30 | </script>
 31 | 
 32 | <style type="text/css">
 33 | * {
 34 | 	-webkit-box-sizing: border-box;
 35 | 	-moz-box-sizing: border-box;
 36 | 	box-sizing: border-box;
 37 | }
 38 | 
 39 | html {
 40 | 	-ms-touch-action: none;
 41 | }
 42 | 
 43 | body,ul,li {
 44 | 	padding: 0;
 45 | 	margin: 0;
 46 | 	border: 0;
 47 | }
 48 | 
 49 | body {
 50 | 	font-size: 12px;
 51 | 	font-family: ubuntu, helvetica, arial;
 52 | 	overflow: hidden; /* this is important to prevent the whole page to bounce */
 53 | }
 54 | 
 55 | #header {
 56 | 	position: absolute;
 57 | 	z-index: 2;
 58 | 	top: 0;
 59 | 	left: 0;
 60 | 	width: 100%;
 61 | 	height: 45px;
 62 | 	line-height: 45px;
 63 | 	background: #CD235C;
 64 | 	padding: 0;
 65 | 	color: #eee;
 66 | 	font-size: 20px;
 67 | 	text-align: center;
 68 | 	font-weight: bold;
 69 | }
 70 | 
 71 | #footer {
 72 | 	position: absolute;
 73 | 	z-index: 2;
 74 | 	bottom: 0;
 75 | 	left: 0;
 76 | 	width: 100%;
 77 | 	height: 48px;
 78 | 	background: #444;
 79 | 	padding: 0;
 80 | 	border-top: 1px solid #444;
 81 | }
 82 | 
 83 | #wrapper {
 84 | 	position: absolute;
 85 | 	z-index: 1;
 86 | 	top: 45px;
 87 | 	bottom: 48px;
 88 | 	left: 0;
 89 | 	width: 100%;
 90 | 	background: #ccc;
 91 | 	overflow: hidden;
 92 | }
 93 | 
 94 | #scroller {
 95 | 	position: absolute;
 96 | 	z-index: 1;
 97 | 	-webkit-tap-highlight-color: rgba(0,0,0,0);
 98 | 	width: 100%;
 99 | 	-webkit-transform: translateZ(0);
100 | 	-moz-transform: translateZ(0);
101 | 	-ms-transform: translateZ(0);
102 | 	-o-transform: translateZ(0);
103 | 	transform: translateZ(0);
104 | 	-webkit-touch-callout: none;
105 | 	-webkit-user-select: none;
106 | 	-moz-user-select: none;
107 | 	-ms-user-select: none;
108 | 	user-select: none;
109 | 	-webkit-text-size-adjust: none;
110 | 	-moz-text-size-adjust: none;
111 | 	-ms-text-size-adjust: none;
112 | 	-o-text-size-adjust: none;
113 | 	text-size-adjust: none;
114 | }
115 | 
116 | #scroller ul {
117 | 	list-style: none;
118 | 	padding: 0;
119 | 	margin: 0;
120 | 	width: 100%;
121 | 	text-align: left;
122 | }
123 | 
124 | #scroller li {
125 | 	padding: 0 10px;
126 | 	height: 40px;
127 | 	line-height: 40px;
128 | 	border-bottom: 1px solid #ccc;
129 | 	border-top: 1px solid #fff;
130 | 	background-color: #fafafa;
131 | 	font-size: 14px;
132 | }
133 | 
134 | </style>
135 | </head>
136 | <body onload="loaded()">
137 | <div id="header">iScroll</div>
138 | 
139 | <div id="wrapper">
140 | 	<div id="scroller">
141 | 		<ul>
142 | 			<li>Pretty row 1</li>
143 | 			<li>Pretty row 2</li>
144 | 			<li>Pretty row 3</li>
145 | 			<li>Pretty row 4</li>
146 | 			<li>Pretty row 5</li>
147 | 			<li>Pretty row 6</li>
148 | 			<li>Pretty row 7</li>
149 | 			<li>Pretty row 8</li>
150 | 			<li>Pretty row 9</li>
151 | 			<li>Pretty row 10</li>
152 | 			<li>Pretty row 11</li>
153 | 			<li>Pretty row 12</li>
154 | 			<li>Pretty row 13</li>
155 | 			<li>Pretty row 14</li>
156 | 			<li>Pretty row 15</li>
157 | 			<li>Pretty row 16</li>
158 | 			<li>Pretty row 17</li>
159 | 			<li>Pretty row 18</li>
160 | 			<li>Pretty row 19</li>
161 | 			<li>Pretty row 20</li>
162 | 			<li>Pretty row 21</li>
163 | 			<li>Pretty row 22</li>
164 | 			<li>Pretty row 23</li>
165 | 			<li>Pretty row 24</li>
166 | 			<li>Pretty row 25</li>
167 | 			<li>Pretty row 26</li>
168 | 			<li>Pretty row 27</li>
169 | 			<li>Pretty row 28</li>
170 | 			<li>Pretty row 29</li>
171 | 			<li>Pretty row 30</li>
172 | 			<li>Pretty row 31</li>
173 | 			<li>Pretty row 32</li>
174 | 			<li>Pretty row 33</li>
175 | 			<li>Pretty row 34</li>
176 | 			<li>Pretty row 35</li>
177 | 			<li>Pretty row 36</li>
178 | 			<li>Pretty row 37</li>
179 | 			<li>Pretty row 38</li>
180 | 			<li>Pretty row 39</li>
181 | 			<li>Pretty row 40</li>
182 | 			<li>Pretty row 41</li>
183 | 			<li>Pretty row 42</li>
184 | 			<li>Pretty row 43</li>
185 | 			<li>Pretty row 44</li>
186 | 			<li>Pretty row 45</li>
187 | 			<li>Pretty row 46</li>
188 | 			<li>Pretty row 47</li>
189 | 			<li>Pretty row 48</li>
190 | 			<li>Pretty row 49</li>
191 | 			<li>Pretty row 50</li>
192 | 		</ul>
193 | 	</div>
194 | </div>
195 | 
196 | <div id="footer"></div>
197 | 
198 | </body>
199 | </html>
200 | 


--------------------------------------------------------------------------------
/demos/simple/index.html:
--------------------------------------------------------------------------------
  1 | <!DOCTYPE html>
  2 | <html>
  3 | <head>
  4 | <meta charset="utf-8">
  5 | <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=0, minimum-scale=1.0, maximum-scale=1.0">
  6 | 
  7 | <title>iScroll demo: simple</title>
  8 | 
  9 | <script type="text/javascript" src="../../build/iscroll.js"></script>
 10 | <script type="text/javascript" src="../demoUtils.js"></script>
 11 | <script type="text/javascript">
 12 | 
 13 | var myScroll;
 14 | 
 15 | function loaded () {
 16 | 	myScroll = new IScroll('#wrapper', { mouseWheel: true });
 17 | }
 18 | 
 19 | document.addEventListener('touchmove', function (e) { e.preventDefault(); }, isPassive() ? {
 20 | 	capture: false,
 21 | 	passive: false
 22 | } : false);
 23 | 
 24 | </script>
 25 | 
 26 | <style type="text/css">
 27 | * {
 28 | 	-webkit-box-sizing: border-box;
 29 | 	-moz-box-sizing: border-box;
 30 | 	box-sizing: border-box;
 31 | }
 32 | 
 33 | html {
 34 | 	-ms-touch-action: none;
 35 | }
 36 | 
 37 | body,ul,li {
 38 | 	padding: 0;
 39 | 	margin: 0;
 40 | 	border: 0;
 41 | }
 42 | 
 43 | body {
 44 | 	font-size: 12px;
 45 | 	font-family: ubuntu, helvetica, arial;
 46 | 	overflow: hidden; /* this is important to prevent the whole page to bounce */
 47 | }
 48 | 
 49 | #header {
 50 | 	position: absolute;
 51 | 	z-index: 2;
 52 | 	top: 0;
 53 | 	left: 0;
 54 | 	width: 100%;
 55 | 	height: 45px;
 56 | 	line-height: 45px;
 57 | 	background: #CD235C;
 58 | 	padding: 0;
 59 | 	color: #eee;
 60 | 	font-size: 20px;
 61 | 	text-align: center;
 62 | 	font-weight: bold;
 63 | }
 64 | 
 65 | #footer {
 66 | 	position: absolute;
 67 | 	z-index: 2;
 68 | 	bottom: 0;
 69 | 	left: 0;
 70 | 	width: 100%;
 71 | 	height: 48px;
 72 | 	background: #444;
 73 | 	padding: 0;
 74 | 	border-top: 1px solid #444;
 75 | }
 76 | 
 77 | #wrapper {
 78 | 	position: absolute;
 79 | 	z-index: 1;
 80 | 	top: 45px;
 81 | 	bottom: 48px;
 82 | 	left: 0;
 83 | 	width: 100%;
 84 | 	background: #ccc;
 85 | 	overflow: hidden;
 86 | }
 87 | 
 88 | #scroller {
 89 | 	position: absolute;
 90 | 	z-index: 1;
 91 | 	-webkit-tap-highlight-color: rgba(0,0,0,0);
 92 | 	width: 100%;
 93 | 	-webkit-transform: translateZ(0);
 94 | 	-moz-transform: translateZ(0);
 95 | 	-ms-transform: translateZ(0);
 96 | 	-o-transform: translateZ(0);
 97 | 	transform: translateZ(0);
 98 | 	-webkit-touch-callout: none;
 99 | 	-webkit-user-select: none;
100 | 	-moz-user-select: none;
101 | 	-ms-user-select: none;
102 | 	user-select: none;
103 | 	-webkit-text-size-adjust: none;
104 | 	-moz-text-size-adjust: none;
105 | 	-ms-text-size-adjust: none;
106 | 	-o-text-size-adjust: none;
107 | 	text-size-adjust: none;
108 | }
109 | 
110 | #scroller ul {
111 | 	list-style: none;
112 | 	padding: 0;
113 | 	margin: 0;
114 | 	width: 100%;
115 | 	text-align: left;
116 | }
117 | 
118 | #scroller li {
119 | 	padding: 0 10px;
120 | 	height: 40px;
121 | 	line-height: 40px;
122 | 	border-bottom: 1px solid #ccc;
123 | 	border-top: 1px solid #fff;
124 | 	background-color: #fafafa;
125 | 	font-size: 14px;
126 | }
127 | 
128 | </style>
129 | </head>
130 | <body onload="loaded()">
131 | <div id="header">iScroll</div>
132 | 
133 | <div id="wrapper">
134 | 	<div id="scroller">
135 | 		<ul>
136 | 			<li>Pretty row 1</li>
137 | 			<li>Pretty row 2</li>
138 | 			<li>Pretty row 3</li>
139 | 			<li>Pretty row 4</li>
140 | 			<li>Pretty row 5</li>
141 | 			<li>Pretty row 6</li>
142 | 			<li>Pretty row 7</li>
143 | 			<li>Pretty row 8</li>
144 | 			<li>Pretty row 9</li>
145 | 			<li>Pretty row 10</li>
146 | 			<li>Pretty row 11</li>
147 | 			<li>Pretty row 12</li>
148 | 			<li>Pretty row 13</li>
149 | 			<li>Pretty row 14</li>
150 | 			<li>Pretty row 15</li>
151 | 			<li>Pretty row 16</li>
152 | 			<li>Pretty row 17</li>
153 | 			<li>Pretty row 18</li>
154 | 			<li>Pretty row 19</li>
155 | 			<li>Pretty row 20</li>
156 | 			<li>Pretty row 21</li>
157 | 			<li>Pretty row 22</li>
158 | 			<li>Pretty row 23</li>
159 | 			<li>Pretty row 24</li>
160 | 			<li>Pretty row 25</li>
161 | 			<li>Pretty row 26</li>
162 | 			<li>Pretty row 27</li>
163 | 			<li>Pretty row 28</li>
164 | 			<li>Pretty row 29</li>
165 | 			<li>Pretty row 30</li>
166 | 			<li>Pretty row 31</li>
167 | 			<li>Pretty row 32</li>
168 | 			<li>Pretty row 33</li>
169 | 			<li>Pretty row 34</li>
170 | 			<li>Pretty row 35</li>
171 | 			<li>Pretty row 36</li>
172 | 			<li>Pretty row 37</li>
173 | 			<li>Pretty row 38</li>
174 | 			<li>Pretty row 39</li>
175 | 			<li>Pretty row 40</li>
176 | 			<li>Pretty row 41</li>
177 | 			<li>Pretty row 42</li>
178 | 			<li>Pretty row 43</li>
179 | 			<li>Pretty row 44</li>
180 | 			<li>Pretty row 45</li>
181 | 			<li>Pretty row 46</li>
182 | 			<li>Pretty row 47</li>
183 | 			<li>Pretty row 48</li>
184 | 			<li>Pretty row 49</li>
185 | 			<li>Pretty row 50</li>
186 | 		</ul>
187 | 	</div>
188 | </div>
189 | 
190 | <div id="footer"></div>
191 | 
192 | </body>
193 | </html>


--------------------------------------------------------------------------------
/demos/snap/index.html:
--------------------------------------------------------------------------------
  1 | <!DOCTYPE html>
  2 | <html>
  3 | <head>
  4 | <meta charset="utf-8">
  5 | <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=0, minimum-scale=1.0, maximum-scale=1.0">
  6 | 
  7 | <title>iScroll demo: snap</title>
  8 | 
  9 | <script type="text/javascript" src="../../build/iscroll.js"></script>
 10 | <script type="text/javascript" src="../demoUtils.js"></script>
 11 | <script type="text/javascript">
 12 | 
 13 | var myScroll;
 14 | 
 15 | function loaded () {
 16 | 	myScroll = new IScroll('#wrapper', {
 17 | 		scrollX: true,
 18 | 		scrollY: true,
 19 | 		momentum: false,
 20 | 		snap: true
 21 | 	});
 22 | }
 23 | 
 24 | document.addEventListener('touchmove', function (e) { e.preventDefault(); }, isPassive() ? {
 25 | 	capture: false,
 26 | 	passive: false
 27 | } : false);
 28 | </script>
 29 | 
 30 | <style type="text/css">
 31 | * {
 32 | 	-webkit-box-sizing: border-box;
 33 | 	-moz-box-sizing: border-box;
 34 | 	box-sizing: border-box;
 35 | }
 36 | 
 37 | html {
 38 | 	-ms-touch-action: none;
 39 | }
 40 | 
 41 | body,ul,li {
 42 | 	padding: 0;
 43 | 	margin: 0;
 44 | 	border: 0;
 45 | }
 46 | 
 47 | body {
 48 | 	font-size: 12px;
 49 | 	font-family: ubuntu, helvetica, arial;
 50 | 	overflow: hidden; /* this is important to prevent the whole page to bounce */
 51 | }
 52 | 
 53 | #header {
 54 | 	position: absolute;
 55 | 	z-index: 2;
 56 | 	top: 0;
 57 | 	left: 0;
 58 | 	width: 100%;
 59 | 	height: 45px;
 60 | 	line-height: 45px;
 61 | 	background: #CD235C;
 62 | 	padding: 0;
 63 | 	color: #eee;
 64 | 	font-size: 20px;
 65 | 	text-align: center;
 66 | 	font-weight: bold;
 67 | }
 68 | 
 69 | #footer {
 70 | 	position: absolute;
 71 | 	z-index: 2;
 72 | 	bottom: 0;
 73 | 	left: 0;
 74 | 	width: 100%;
 75 | 	height: 48px;
 76 | 	background: #444;
 77 | 	padding: 0;
 78 | 	border-top: 1px solid #444;
 79 | }
 80 | 
 81 | #wrapper {
 82 | 	position: absolute;
 83 | 	z-index: 1;
 84 | 	top: 45px;
 85 | 	bottom: 48px;
 86 | 	left: 0;
 87 | 	width: 100%;
 88 | 	background: #ccc;
 89 | 	overflow: hidden;
 90 | }
 91 | 
 92 | #scroller {
 93 | 	position: absolute;
 94 | 	z-index: 1;
 95 | 	-webkit-tap-highlight-color: rgba(0,0,0,0);
 96 | 	width: 2000px;
 97 | 	height: 2000px;
 98 | 	background-color: #a00;
 99 | 	-webkit-transform: translateZ(0);
100 | 	-moz-transform: translateZ(0);
101 | 	-ms-transform: translateZ(0);
102 | 	-o-transform: translateZ(0);
103 | 	transform: translateZ(0);
104 | 	-webkit-touch-callout: none;
105 | 	-webkit-user-select: none;
106 | 	-moz-user-select: none;
107 | 	-ms-user-select: none;
108 | 	user-select: none;
109 | 	-webkit-text-size-adjust: none;
110 | 	-moz-text-size-adjust: none;
111 | 	-ms-text-size-adjust: none;
112 | 	-o-text-size-adjust: none;
113 | 	text-size-adjust: none;
114 | }
115 | 
116 | #scroller ul {
117 | 	list-style: none;
118 | 	padding: 0;
119 | 	margin: 0;
120 | 	width: 100%;
121 | 	text-align: center;
122 | }
123 | 
124 | #scroller li {
125 | 	display: block;
126 | 	float: left;
127 | 	width: 200px;
128 | 	height: 200px;
129 | 	border-right: 1px solid #ccc;
130 | 	border-bottom: 1px solid #ccc;
131 | 	background-color: #fafafa;
132 | 	font-size: 14px;
133 | }
134 | 
135 | </style>
136 | </head>
137 | <body onload="loaded()">
138 | <div id="header">iScroll</div>
139 | 
140 | <div id="wrapper">
141 | 	<div id="scroller">
142 | 		<ul>
143 | 			<li>Cell</li>
144 | 			<li>Cell</li>
145 | 			<li>Cell</li>
146 | 			<li>Cell</li>
147 | 			<li>Cell</li>
148 | 			<li>Cell</li>
149 | 			<li>Cell</li>
150 | 			<li>Cell</li>
151 | 			<li>Cell</li>
152 | 			<li>Cell</li>
153 | 
154 | 			<li>Cell</li>
155 | 			<li>Cell</li>
156 | 			<li>Cell</li>
157 | 			<li>Cell</li>
158 | 			<li>Cell</li>
159 | 			<li>Cell</li>
160 | 			<li>Cell</li>
161 | 			<li>Cell</li>
162 | 			<li>Cell</li>
163 | 			<li>Cell</li>
164 | 
165 | 			<li>Cell</li>
166 | 			<li>Cell</li>
167 | 			<li>Cell</li>
168 | 			<li>Cell</li>
169 | 			<li>Cell</li>
170 | 			<li>Cell</li>
171 | 			<li>Cell</li>
172 | 			<li>Cell</li>
173 | 			<li>Cell</li>
174 | 			<li>Cell</li>
175 | 
176 | 			<li>Cell</li>
177 | 			<li>Cell</li>
178 | 			<li>Cell</li>
179 | 			<li>Cell</li>
180 | 			<li>Cell</li>
181 | 			<li>Cell</li>
182 | 			<li>Cell</li>
183 | 			<li>Cell</li>
184 | 			<li>Cell</li>
185 | 			<li>Cell</li>
186 | 
187 | 			<li>Cell</li>
188 | 			<li>Cell</li>
189 | 			<li>Cell</li>
190 | 			<li>Cell</li>
191 | 			<li>Cell</li>
192 | 			<li>Cell</li>
193 | 			<li>Cell</li>
194 | 			<li>Cell</li>
195 | 			<li>Cell</li>
196 | 			<li>Cell</li>
197 | 
198 | 			<li>Cell</li>
199 | 			<li>Cell</li>
200 | 			<li>Cell</li>
201 | 			<li>Cell</li>
202 | 			<li>Cell</li>
203 | 			<li>Cell</li>
204 | 			<li>Cell</li>
205 | 			<li>Cell</li>
206 | 			<li>Cell</li>
207 | 			<li>Cell</li>
208 | 
209 | 			<li>Cell</li>
210 | 			<li>Cell</li>
211 | 			<li>Cell</li>
212 | 			<li>Cell</li>
213 | 			<li>Cell</li>
214 | 			<li>Cell</li>
215 | 			<li>Cell</li>
216 | 			<li>Cell</li>
217 | 			<li>Cell</li>
218 | 			<li>Cell</li>
219 | 
220 | 			<li>Cell</li>
221 | 			<li>Cell</li>
222 | 			<li>Cell</li>
223 | 			<li>Cell</li>
224 | 			<li>Cell</li>
225 | 			<li>Cell</li>
226 | 			<li>Cell</li>
227 | 			<li>Cell</li>
228 | 			<li>Cell</li>
229 | 			<li>Cell</li>
230 | 
231 | 			<li>Cell</li>
232 | 			<li>Cell</li>
233 | 			<li>Cell</li>
234 | 			<li>Cell</li>
235 | 			<li>Cell</li>
236 | 			<li>Cell</li>
237 | 			<li>Cell</li>
238 | 			<li>Cell</li>
239 | 			<li>Cell</li>
240 | 			<li>Cell</li>
241 | 
242 | 			<li>Cell</li>
243 | 			<li>Cell</li>
244 | 			<li>Cell</li>
245 | 			<li>Cell</li>
246 | 			<li>Cell</li>
247 | 			<li>Cell</li>
248 | 			<li>Cell</li>
249 | 			<li>Cell</li>
250 | 			<li>Cell</li>
251 | 			<li>Cell</li>
252 | 		</ul>
253 | 	</div>
254 | </div>
255 | 
256 | <div id="footer"></div>
257 | 
258 | </body>
259 | </html>


--------------------------------------------------------------------------------
/demos/styled-scrollbars/index.html:
--------------------------------------------------------------------------------
  1 | <!DOCTYPE html>
  2 | <html>
  3 | <head>
  4 | <meta charset="utf-8">
  5 | <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=0, minimum-scale=1.0, maximum-scale=1.0">
  6 | 
  7 | <title>iScroll demo: styled scrollbars</title>
  8 | 
  9 | <script type="text/javascript" src="../../build/iscroll.js"></script>
 10 | <script type="text/javascript" src="../demoUtils.js"></script>
 11 | <script type="text/javascript">
 12 | 
 13 | var myScroll;
 14 | 
 15 | function loaded () {
 16 | 	myScroll = new IScroll('#wrapper', { scrollX: true, scrollbars: 'custom' });
 17 | }
 18 | 
 19 | document.addEventListener('touchmove', function (e) { e.preventDefault(); }, isPassive() ? {
 20 | 	capture: false,
 21 | 	passive: false
 22 | } : false);
 23 | 
 24 | </script>
 25 | 
 26 | <style type="text/css">
 27 | 
 28 | /* Styled scrollbars */
 29 | 
 30 | .iScrollHorizontalScrollbar {
 31 | 	position: absolute;
 32 | 	z-index: 9999;
 33 | 	height: 16px;
 34 | 	left: 2px;
 35 | 	right: 2px;
 36 | 	bottom: 2px;
 37 | 	overflow: hidden;
 38 | }
 39 | 
 40 | .iScrollHorizontalScrollbar.iScrollBothScrollbars {
 41 | 	right: 18px;
 42 | }
 43 | 
 44 | .iScrollVerticalScrollbar {
 45 | 	position: absolute;
 46 | 	z-index: 9999;
 47 | 	width: 16px;
 48 | 	bottom: 2px;
 49 | 	top: 2px;
 50 | 	right: 2px;
 51 | 	overflow: hidden;
 52 | }
 53 | 
 54 | .iScrollVerticalScrollbar.iScrollBothScrollbars {
 55 | 	bottom: 18px;
 56 | }
 57 | 
 58 | .iScrollIndicator {
 59 | 	position: absolute;
 60 | 	background: #cc3f6e;
 61 | 	border-width: 1px;
 62 | 	border-style: solid;
 63 | 	border-color: #EB97B4 #7C2845 #7C2845 #EB97B4;
 64 | 	border-radius: 8px;
 65 | }
 66 | 
 67 | .iScrollHorizontalScrollbar .iScrollIndicator {
 68 | 	height: 100%;
 69 | 	background: -moz-linear-gradient(left,  #cc3f6e 0%, #93004e 100%);
 70 | 	background: -webkit-linear-gradient(left,  #cc3f6e 0%,#93004e 100%);
 71 | 	background: -o-linear-gradient(left,  #cc3f6e 0%,#93004e 100%);
 72 | 	background: -ms-linear-gradient(left,  #cc3f6e 0%,#93004e 100%);
 73 | 	background: linear-gradient(to right,  #cc3f6e 0%,#93004e 100%);
 74 | }
 75 | 
 76 | .iScrollVerticalScrollbar .iScrollIndicator {
 77 | 	width: 100%;
 78 | 	background: -moz-linear-gradient(top, #cc3f6e 0%, #93004e 100%);
 79 | 	background: -webkit-linear-gradient(top,  #cc3f6e 0%,#93004e 100%);
 80 | 	background: -o-linear-gradient(top, #cc3f6e 0%,#93004e 100%);
 81 | 	background: -ms-linear-gradient(top, #cc3f6e 0%,#93004e 100%);
 82 | 	background: linear-gradient(to bottom,  #cc3f6e 0%,#93004e 100%);
 83 | }
 84 | 
 85 | 
 86 | /* end */
 87 | 
 88 | * {
 89 | 	-webkit-box-sizing: border-box;
 90 | 	-moz-box-sizing: border-box;
 91 | 	box-sizing: border-box;
 92 | }
 93 | 
 94 | html {
 95 | 	-ms-touch-action: none;
 96 | }
 97 | 
 98 | body,ul,li {
 99 | 	padding: 0;
100 | 	margin: 0;
101 | 	border: 0;
102 | }
103 | 
104 | body {
105 | 	font-size: 12px;
106 | 	font-family: ubuntu, helvetica, arial;
107 | 	overflow: hidden; /* this is important to prevent the whole page to bounce */
108 | }
109 | 
110 | #header {
111 | 	position: absolute;
112 | 	z-index: 2;
113 | 	top: 0;
114 | 	left: 0;
115 | 	width: 100%;
116 | 	height: 45px;
117 | 	line-height: 45px;
118 | 	background: #CD235C;
119 | 	padding: 0;
120 | 	color: #eee;
121 | 	font-size: 20px;
122 | 	text-align: center;
123 | 	font-weight: bold;
124 | }
125 | 
126 | #footer {
127 | 	position: absolute;
128 | 	z-index: 2;
129 | 	bottom: 0;
130 | 	left: 0;
131 | 	width: 100%;
132 | 	height: 48px;
133 | 	background: #444;
134 | 	padding: 0;
135 | 	border-top: 1px solid #444;
136 | }
137 | 
138 | #wrapper {
139 | 	position: absolute;
140 | 	z-index: 1;
141 | 	top: 45px;
142 | 	bottom: 48px;
143 | 	left: 0;
144 | 	width: 100%;
145 | 	background: #ccc;
146 | 	overflow: hidden;
147 | }
148 | 
149 | #scroller {
150 | 	position: absolute;
151 | 	z-index: 1;
152 | 	-webkit-tap-highlight-color: rgba(0,0,0,0);
153 | 	width: 2000px;
154 | 	-webkit-transform: translateZ(0);
155 | 	-moz-transform: translateZ(0);
156 | 	-ms-transform: translateZ(0);
157 | 	-o-transform: translateZ(0);
158 | 	transform: translateZ(0);
159 | 	-webkit-touch-callout: none;
160 | 	-webkit-user-select: none;
161 | 	-moz-user-select: none;
162 | 	-ms-user-select: none;
163 | 	user-select: none;
164 | 	-webkit-text-size-adjust: none;
165 | 	-moz-text-size-adjust: none;
166 | 	-ms-text-size-adjust: none;
167 | 	-o-text-size-adjust: none;
168 | 	text-size-adjust: none;
169 | }
170 | 
171 | #scroller ul {
172 | 	list-style: none;
173 | 	padding: 0;
174 | 	margin: 0;
175 | 	width: 100%;
176 | 	text-align: left;
177 | }
178 | 
179 | #scroller li {
180 | 	padding: 0 10px;
181 | 	height: 40px;
182 | 	line-height: 40px;
183 | 	border-bottom: 1px solid #ccc;
184 | 	border-top: 1px solid #fff;
185 | 	background-color: #fafafa;
186 | 	font-size: 14px;
187 | }
188 | 
189 | </style>
190 | </head>
191 | <body onload="loaded()">
192 | <div id="header">iScroll</div>
193 | 
194 | <div id="wrapper">
195 | 	<div id="scroller">
196 | 		<ul>
197 | 			<li>Pretty row 1</li>
198 | 			<li>Pretty row 2</li>
199 | 			<li>Pretty row 3</li>
200 | 			<li>Pretty row 4</li>
201 | 			<li>Pretty row 5</li>
202 | 			<li>Pretty row 6</li>
203 | 			<li>Pretty row 7</li>
204 | 			<li>Pretty row 8</li>
205 | 			<li>Pretty row 9</li>
206 | 			<li>Pretty row 10</li>
207 | 			<li>Pretty row 11</li>
208 | 			<li>Pretty row 12</li>
209 | 			<li>Pretty row 13</li>
210 | 			<li>Pretty row 14</li>
211 | 			<li>Pretty row 15</li>
212 | 			<li>Pretty row 16</li>
213 | 			<li>Pretty row 17</li>
214 | 			<li>Pretty row 18</li>
215 | 			<li>Pretty row 19</li>
216 | 			<li>Pretty row 20</li>
217 | 			<li>Pretty row 21</li>
218 | 			<li>Pretty row 22</li>
219 | 			<li>Pretty row 23</li>
220 | 			<li>Pretty row 24</li>
221 | 			<li>Pretty row 25</li>
222 | 			<li>Pretty row 26</li>
223 | 			<li>Pretty row 27</li>
224 | 			<li>Pretty row 28</li>
225 | 			<li>Pretty row 29</li>
226 | 			<li>Pretty row 30</li>
227 | 			<li>Pretty row 31</li>
228 | 			<li>Pretty row 32</li>
229 | 			<li>Pretty row 33</li>
230 | 			<li>Pretty row 34</li>
231 | 			<li>Pretty row 35</li>
232 | 			<li>Pretty row 36</li>
233 | 			<li>Pretty row 37</li>
234 | 			<li>Pretty row 38</li>
235 | 			<li>Pretty row 39</li>
236 | 			<li>Pretty row 40</li>
237 | 			<li>Pretty row 41</li>
238 | 			<li>Pretty row 42</li>
239 | 			<li>Pretty row 43</li>
240 | 			<li>Pretty row 44</li>
241 | 			<li>Pretty row 45</li>
242 | 			<li>Pretty row 46</li>
243 | 			<li>Pretty row 47</li>
244 | 			<li>Pretty row 48</li>
245 | 			<li>Pretty row 49</li>
246 | 			<li>Pretty row 50</li>
247 | 		</ul>
248 | 	</div>
249 | </div>
250 | 
251 | <div id="footer"></div>
252 | 
253 | </body>
254 | </html>


--------------------------------------------------------------------------------
/demos/tap/index.html:
--------------------------------------------------------------------------------
  1 | <!DOCTYPE html>
  2 | <html>
  3 | <head>
  4 | <meta charset="utf-8">
  5 | <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=0, minimum-scale=1.0, maximum-scale=1.0">
  6 | 
  7 | <title>iScroll demo: simple</title>
  8 | 
  9 | <script type="text/javascript" src="../../build/iscroll.js"></script>
 10 | <script type="text/javascript" src="../demoUtils.js"></script>
 11 | <script type="text/javascript">
 12 | 
 13 | var myScroll;
 14 | 
 15 | function loaded () {
 16 | 	myScroll = new IScroll('#wrapper', { mouseWheel: true, tap: true });
 17 | 
 18 | 	document.getElementById('me').addEventListener('tap', function () {
 19 | 		this.style.background = !this.style.background ? '#a00' : '';
 20 | 	}, false);
 21 | }
 22 | 
 23 | document.addEventListener('touchmove', function (e) { e.preventDefault(); }, isPassive() ? {
 24 | 	capture: false,
 25 | 	passive: false
 26 | } : false);
 27 | 
 28 | </script>
 29 | 
 30 | <style type="text/css">
 31 | * {
 32 | 	-webkit-box-sizing: border-box;
 33 | 	-moz-box-sizing: border-box;
 34 | 	box-sizing: border-box;
 35 | }
 36 | 
 37 | html {
 38 | 	-ms-touch-action: none;
 39 | }
 40 | 
 41 | body,ul,li {
 42 | 	padding: 0;
 43 | 	margin: 0;
 44 | 	border: 0;
 45 | }
 46 | 
 47 | body {
 48 | 	font-size: 12px;
 49 | 	font-family: ubuntu, helvetica, arial;
 50 | 	overflow: hidden; /* this is important to prevent the whole page to bounce */
 51 | }
 52 | 
 53 | #header {
 54 | 	position: absolute;
 55 | 	z-index: 2;
 56 | 	top: 0;
 57 | 	left: 0;
 58 | 	width: 100%;
 59 | 	height: 45px;
 60 | 	line-height: 45px;
 61 | 	background: #CD235C;
 62 | 	padding: 0;
 63 | 	color: #eee;
 64 | 	font-size: 20px;
 65 | 	text-align: center;
 66 | 	font-weight: bold;
 67 | }
 68 | 
 69 | #footer {
 70 | 	position: absolute;
 71 | 	z-index: 2;
 72 | 	bottom: 0;
 73 | 	left: 0;
 74 | 	width: 100%;
 75 | 	height: 48px;
 76 | 	background: #444;
 77 | 	padding: 0;
 78 | 	border-top: 1px solid #444;
 79 | }
 80 | 
 81 | #wrapper {
 82 | 	position: absolute;
 83 | 	z-index: 1;
 84 | 	top: 45px;
 85 | 	bottom: 48px;
 86 | 	left: 0;
 87 | 	width: 100%;
 88 | 	background: #ccc;
 89 | 	overflow: hidden;
 90 | }
 91 | 
 92 | #scroller {
 93 | 	position: absolute;
 94 | 	z-index: 1;
 95 | 	-webkit-tap-highlight-color: rgba(0,0,0,0);
 96 | 	width: 100%;
 97 | 	-webkit-transform: translateZ(0);
 98 | 	-moz-transform: translateZ(0);
 99 | 	-ms-transform: translateZ(0);
100 | 	-o-transform: translateZ(0);
101 | 	transform: translateZ(0);
102 | 	-webkit-touch-callout: none;
103 | 	-webkit-user-select: none;
104 | 	-moz-user-select: none;
105 | 	-ms-user-select: none;
106 | 	user-select: none;
107 | 	-webkit-text-size-adjust: none;
108 | 	-moz-text-size-adjust: none;
109 | 	-ms-text-size-adjust: none;
110 | 	-o-text-size-adjust: none;
111 | 	text-size-adjust: none;
112 | }
113 | 
114 | #scroller ul {
115 | 	list-style: none;
116 | 	padding: 0;
117 | 	margin: 0;
118 | 	width: 100%;
119 | 	text-align: left;
120 | }
121 | 
122 | #scroller li {
123 | 	padding: 0 10px;
124 | 	height: 40px;
125 | 	line-height: 40px;
126 | 	border-bottom: 1px solid #ccc;
127 | 	border-top: 1px solid #fff;
128 | 	background-color: #fafafa;
129 | 	font-size: 14px;
130 | }
131 | 
132 | </style>
133 | </head>
134 | <body onload="loaded()">
135 | <div id="header">iScroll</div>
136 | 
137 | <div id="wrapper">
138 | 	<div id="scroller">
139 | 		<ul>
140 | 			<li>Pretty row 1</li>
141 | 			<li>Pretty row 2</li>
142 | 			<li>Pretty row 3</li>
143 | 			<li>Pretty row 4</li>
144 | 			<li>Pretty row 5</li>
145 | 			<li id="me"><strong>Tap me! Tap me! Tap me! Tap me!</strong></li>
146 | 			<li>Pretty row 7</li>
147 | 			<li>Pretty row 8</li>
148 | 			<li>Pretty row 9</li>
149 | 			<li>Pretty row 10</li>
150 | 			<li>Pretty row 11</li>
151 | 			<li>Pretty row 12</li>
152 | 			<li>Pretty row 13</li>
153 | 			<li>Pretty row 14</li>
154 | 			<li>Pretty row 15</li>
155 | 			<li>Pretty row 16</li>
156 | 			<li>Pretty row 17</li>
157 | 			<li>Pretty row 18</li>
158 | 			<li>Pretty row 19</li>
159 | 			<li>Pretty row 20</li>
160 | 			<li>Pretty row 21</li>
161 | 			<li>Pretty row 22</li>
162 | 			<li>Pretty row 23</li>
163 | 			<li>Pretty row 24</li>
164 | 			<li>Pretty row 25</li>
165 | 			<li>Pretty row 26</li>
166 | 			<li>Pretty row 27</li>
167 | 			<li>Pretty row 28</li>
168 | 			<li>Pretty row 29</li>
169 | 			<li>Pretty row 30</li>
170 | 			<li>Pretty row 31</li>
171 | 			<li>Pretty row 32</li>
172 | 			<li>Pretty row 33</li>
173 | 			<li>Pretty row 34</li>
174 | 			<li>Pretty row 35</li>
175 | 			<li>Pretty row 36</li>
176 | 			<li>Pretty row 37</li>
177 | 			<li>Pretty row 38</li>
178 | 			<li>Pretty row 39</li>
179 | 			<li>Pretty row 40</li>
180 | 			<li>Pretty row 41</li>
181 | 			<li>Pretty row 42</li>
182 | 			<li>Pretty row 43</li>
183 | 			<li>Pretty row 44</li>
184 | 			<li>Pretty row 45</li>
185 | 			<li>Pretty row 46</li>
186 | 			<li>Pretty row 47</li>
187 | 			<li>Pretty row 48</li>
188 | 			<li>Pretty row 49</li>
189 | 			<li>Pretty row 50</li>
190 | 		</ul>
191 | 	</div>
192 | </div>
193 | 
194 | <div id="footer"></div>
195 | 
196 | </body>
197 | </html>


--------------------------------------------------------------------------------
/demos/zoom/index.html:
--------------------------------------------------------------------------------
  1 | <!DOCTYPE html>
  2 | <html>
  3 | <head>
  4 | <meta charset="utf-8">
  5 | <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=0, minimum-scale=1.0, maximum-scale=1.0">
  6 | 
  7 | <title>iScroll demo: zoom</title>
  8 | 
  9 | <script type="text/javascript" src="../../build/iscroll-zoom.js"></script>
 10 | <script type="text/javascript" src="../demoUtils.js"></script>
 11 | <script type="text/javascript">
 12 | 
 13 | var myScroll;
 14 | 
 15 | function loaded () {
 16 | 	myScroll = new IScroll('#wrapper', {
 17 | 		zoom: true,
 18 | 		scrollX: true,
 19 | 		scrollY: true,
 20 | 		mouseWheel: true,
 21 | 		wheelAction: 'zoom'
 22 | 	});
 23 | }
 24 | 
 25 | document.addEventListener('touchmove', function (e) { e.preventDefault(); }, isPassive() ? {
 26 | 	capture: false,
 27 | 	passive: false
 28 | } : false);
 29 | 
 30 | </script>
 31 | 
 32 | <style type="text/css">
 33 | * {
 34 | 	-webkit-box-sizing: border-box;
 35 | 	-moz-box-sizing: border-box;
 36 | 	box-sizing: border-box;
 37 | }
 38 | 
 39 | html {
 40 | 	-ms-touch-action: none;
 41 | }
 42 | 
 43 | body,ul,li {
 44 | 	padding: 0;
 45 | 	margin: 0;
 46 | 	border: 0;
 47 | }
 48 | 
 49 | body {
 50 | 	font-size: 12px;
 51 | 	font-family: ubuntu, helvetica, arial;
 52 | 	overflow: hidden; /* this is important to prevent the whole page to bounce */
 53 | }
 54 | 
 55 | #wrapper {
 56 | 	position: absolute;
 57 | 	z-index: 1;
 58 | 	top: 50px;
 59 | 	bottom: 50px;
 60 | 	left: 50px;
 61 | 	right: 50px;
 62 | 	background: #ccc;
 63 | 	overflow: hidden;
 64 | }
 65 | 
 66 | #scroller {
 67 | 	position: absolute;
 68 | 	z-index: 1;
 69 | 	-webkit-tap-highlight-color: rgba(0,0,0,0);
 70 | 	width: 100%;
 71 | 	-webkit-transform: translateZ(0);
 72 | 	-moz-transform: translateZ(0);
 73 | 	-ms-transform: translateZ(0);
 74 | 	-o-transform: translateZ(0);
 75 | 	transform: translateZ(0);
 76 | 	-webkit-touch-callout: none;
 77 | 	-webkit-user-select: none;
 78 | 	-moz-user-select: none;
 79 | 	-ms-user-select: none;
 80 | 	user-select: none;
 81 | 	-webkit-text-size-adjust: none;
 82 | 	-moz-text-size-adjust: none;
 83 | 	-ms-text-size-adjust: none;
 84 | 	-o-text-size-adjust: none;
 85 | 	text-size-adjust: none;
 86 | }
 87 | 
 88 | #scroller ul {
 89 | 	list-style: none;
 90 | 	padding: 0;
 91 | 	margin: 0;
 92 | 	width: 100%;
 93 | 	text-align: left;
 94 | }
 95 | 
 96 | #scroller li {
 97 | 	padding: 0 10px;
 98 | 	height: 40px;
 99 | 	line-height: 40px;
100 | 	border-bottom: 1px solid #ccc;
101 | 	border-top: 1px solid #fff;
102 | 	background-color: #fafafa;
103 | 	font-size: 14px;
104 | }
105 | 
106 | </style>
107 | </head>
108 | <body onload="loaded()">
109 | 
110 | <div id="wrapper">
111 | 	<div id="scroller">
112 | 		<ul>
113 | 			<li>Pretty row 1</li>
114 | 			<li>Pretty row 2</li>
115 | 			<li>Pretty row 3</li>
116 | 			<li>Pretty row 4</li>
117 | 			<li>Pretty row 5</li>
118 | 			<li>Pretty row 6</li>
119 | 			<li>Pretty row 7</li>
120 | 			<li>Pretty row 8</li>
121 | 			<li>Pretty row 9</li>
122 | 			<li>Pretty row 10</li>
123 | 			<li>Pretty row 11</li>
124 | 			<li>Pretty row 12</li>
125 | 			<li>Pretty row 13</li>
126 | 			<li>Pretty row 14</li>
127 | 			<li>Pretty row 15</li>
128 | 			<li>Pretty row 16</li>
129 | 			<li>Pretty row 17</li>
130 | 			<li>Pretty row 18</li>
131 | 			<li>Pretty row 19</li>
132 | 			<li>Pretty row 20</li>
133 | 			<li>Pretty row 21</li>
134 | 			<li>Pretty row 22</li>
135 | 			<li>Pretty row 23</li>
136 | 			<li>Pretty row 24</li>
137 | 			<li>Pretty row 25</li>
138 | 			<li>Pretty row 26</li>
139 | 			<li>Pretty row 27</li>
140 | 			<li>Pretty row 28</li>
141 | 			<li>Pretty row 29</li>
142 | 			<li>Pretty row 30</li>
143 | 			<li>Pretty row 31</li>
144 | 			<li>Pretty row 32</li>
145 | 			<li>Pretty row 33</li>
146 | 			<li>Pretty row 34</li>
147 | 			<li>Pretty row 35</li>
148 | 			<li>Pretty row 36</li>
149 | 			<li>Pretty row 37</li>
150 | 			<li>Pretty row 38</li>
151 | 			<li>Pretty row 39</li>
152 | 			<li>Pretty row 40</li>
153 | 			<li>Pretty row 41</li>
154 | 			<li>Pretty row 42</li>
155 | 			<li>Pretty row 43</li>
156 | 			<li>Pretty row 44</li>
157 | 			<li>Pretty row 45</li>
158 | 			<li>Pretty row 46</li>
159 | 			<li>Pretty row 47</li>
160 | 			<li>Pretty row 48</li>
161 | 			<li>Pretty row 49</li>
162 | 			<li>Pretty row 50</li>
163 | 		</ul>
164 | 	</div>
165 | </div>
166 | 
167 | </body>
168 | </html>


--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
 1 | {
 2 |   "name": "iscroll",
 3 |   "description": "Smooth scrolling for the web",
 4 |   "version": "5.2.0-snapshot",
 5 |   "homepage": "http://iscrolljs.com",
 6 |   "author": "Matteo Spinelli <matteo@cubiq.org> (http://cubiq.org)",
 7 |   "keywords": [
 8 |     "scrolling",
 9 |     "carousel",
10 |     "zoom",
11 |     "iphone",
12 |     "android",
13 |     "mobile",
14 |     "desktop"
15 |   ],
16 |   "main": "build/iscroll.js",
17 |   "devDependencies": {
18 |     "jshint": "~2.9.1",
19 |     "uglify-js": "~2.6.2"
20 |   },
21 |   "repository": {
22 |     "type": "git",
23 |     "url": "https://github.com/cubiq/iscroll.git"
24 |   },
25 |   "bugs": {
26 |     "url": "https://github.com/cubiq/iscroll/issues"
27 |   },
28 |   "license": "MIT"
29 | }
30 | 


--------------------------------------------------------------------------------
/src/close.js:
--------------------------------------------------------------------------------
 1 | 
 2 | IScroll.utils = utils;
 3 | 
 4 | if ( typeof module != 'undefined' && module.exports ) {
 5 | 	module.exports = IScroll;
 6 | } else if ( typeof define == 'function' && define.amd ) {
 7 |         define( function () { return IScroll; } );
 8 | } else {
 9 | 	window.IScroll = IScroll;
10 | }
11 | 
12 | })(window, document, Math);
13 | 


--------------------------------------------------------------------------------
/src/core.js:
--------------------------------------------------------------------------------
  1 | 
  2 | function IScroll (el, options) {
  3 | 	this.wrapper = typeof el == 'string' ? document.querySelector(el) : el;
  4 | 	this.scroller = this.wrapper.children[0];
  5 | 	this.scrollerStyle = this.scroller.style;		// cache style for better performance
  6 | 
  7 | 	this.options = {
  8 | 
  9 | // INSERT POINT: OPTIONS
 10 | 		disablePointer : !utils.hasPointer,
 11 | 		disableTouch : utils.hasPointer || !utils.hasTouch,
 12 | 		disableMouse : utils.hasPointer || utils.hasTouch,
 13 | 		startX: 0,
 14 | 		startY: 0,
 15 | 		scrollY: true,
 16 | 		directionLockThreshold: 5,
 17 | 		momentum: true,
 18 | 
 19 | 		bounce: true,
 20 | 		bounceTime: 600,
 21 | 		bounceEasing: '',
 22 | 
 23 | 		preventDefault: true,
 24 | 		preventDefaultException: { tagName: /^(INPUT|TEXTAREA|BUTTON|SELECT)$/ },
 25 | 
 26 | 		HWCompositing: true,
 27 | 		useTransition: true,
 28 | 		useTransform: true,
 29 | 		bindToWrapper: typeof window.onmousedown === "undefined"
 30 | 	};
 31 | 
 32 | 	for ( var i in options ) {
 33 | 		this.options[i] = options[i];
 34 | 	}
 35 | 
 36 | 	// Normalize options
 37 | 	this.translateZ = this.options.HWCompositing && utils.hasPerspective ? ' translateZ(0)' : '';
 38 | 
 39 | 	this.options.useTransition = utils.hasTransition && this.options.useTransition;
 40 | 	this.options.useTransform = utils.hasTransform && this.options.useTransform;
 41 | 
 42 | 	this.options.eventPassthrough = this.options.eventPassthrough === true ? 'vertical' : this.options.eventPassthrough;
 43 | 	this.options.preventDefault = !this.options.eventPassthrough && this.options.preventDefault;
 44 | 
 45 | 	// If you want eventPassthrough I have to lock one of the axes
 46 | 	this.options.scrollY = this.options.eventPassthrough == 'vertical' ? false : this.options.scrollY;
 47 | 	this.options.scrollX = this.options.eventPassthrough == 'horizontal' ? false : this.options.scrollX;
 48 | 
 49 | 	// With eventPassthrough we also need lockDirection mechanism
 50 | 	this.options.freeScroll = this.options.freeScroll && !this.options.eventPassthrough;
 51 | 	this.options.directionLockThreshold = this.options.eventPassthrough ? 0 : this.options.directionLockThreshold;
 52 | 
 53 | 	this.options.bounceEasing = typeof this.options.bounceEasing == 'string' ? utils.ease[this.options.bounceEasing] || utils.ease.circular : this.options.bounceEasing;
 54 | 
 55 | 	this.options.resizePolling = this.options.resizePolling === undefined ? 60 : this.options.resizePolling;
 56 | 
 57 | 	if ( this.options.tap === true ) {
 58 | 		this.options.tap = 'tap';
 59 | 	}
 60 | 
 61 | 	// https://github.com/cubiq/iscroll/issues/1029
 62 | 	if (!this.options.useTransition && !this.options.useTransform) {
 63 | 		if(!(/relative|absolute/i).test(this.scrollerStyle.position)) {
 64 | 			this.scrollerStyle.position = "relative";
 65 | 		}
 66 | 	}
 67 | 
 68 | // INSERT POINT: NORMALIZATION
 69 | 
 70 | 	// Some defaults
 71 | 	this.x = 0;
 72 | 	this.y = 0;
 73 | 	this.directionX = 0;
 74 | 	this.directionY = 0;
 75 | 	this._events = {};
 76 | 
 77 | // INSERT POINT: DEFAULTS
 78 | 
 79 | 	this._init();
 80 | 	this.refresh();
 81 | 
 82 | 	this.scrollTo(this.options.startX, this.options.startY);
 83 | 	this.enable();
 84 | }
 85 | 
 86 | IScroll.prototype = {
 87 | 	version: '/* VERSION */',
 88 | 
 89 | 	_init: function () {
 90 | 		this._initEvents();
 91 | 
 92 | // INSERT POINT: _init
 93 | 
 94 | 	},
 95 | 
 96 | 	destroy: function () {
 97 | 		this._initEvents(true);
 98 | 		clearTimeout(this.resizeTimeout);
 99 |  		this.resizeTimeout = null;
100 | 		this._execEvent('destroy');
101 | 	},
102 | 
103 | 	_transitionEnd: function (e) {
104 | 		if ( e.target != this.scroller || !this.isInTransition ) {
105 | 			return;
106 | 		}
107 | 
108 | 		this._transitionTime();
109 | 		if ( !this.resetPosition(this.options.bounceTime) ) {
110 | 			this.isInTransition = false;
111 | 			this._execEvent('scrollEnd');
112 | 		}
113 | 	},
114 | 
115 | 	_start: function (e) {
116 | 		// React to left mouse button only
117 | 		if ( utils.eventType[e.type] != 1 ) {
118 | 		  // for button property
119 | 		  // http://unixpapa.com/js/mouse.html
120 | 		  var button;
121 | 	    if (!e.which) {
122 | 	      /* IE case */
123 | 	      button = (e.button < 2) ? 0 :
124 | 	               ((e.button == 4) ? 1 : 2);
125 | 	    } else {
126 | 	      /* All others */
127 | 	      button = e.button;
128 | 	    }
129 | 			if ( button !== 0 ) {
130 | 				return;
131 | 			}
132 | 		}
133 | 
134 | 		if ( !this.enabled || (this.initiated && utils.eventType[e.type] !== this.initiated) ) {
135 | 			return;
136 | 		}
137 | 
138 | 		if ( this.options.preventDefault && !utils.isBadAndroid && !utils.preventDefaultException(e.target, this.options.preventDefaultException) ) {
139 | 			e.preventDefault();
140 | 		}
141 | 
142 | 		var point = e.touches ? e.touches[0] : e,
143 | 			pos;
144 | 
145 | 		this.initiated	= utils.eventType[e.type];
146 | 		this.moved		= false;
147 | 		this.distX		= 0;
148 | 		this.distY		= 0;
149 | 		this.directionX = 0;
150 | 		this.directionY = 0;
151 | 		this.directionLocked = 0;
152 | 
153 | 		this.startTime = utils.getTime();
154 | 
155 | 		if ( this.options.useTransition && this.isInTransition ) {
156 | 			this._transitionTime();
157 | 			this.isInTransition = false;
158 | 			pos = this.getComputedPosition();
159 | 			this._translate(Math.round(pos.x), Math.round(pos.y));
160 | 			this._execEvent('scrollEnd');
161 | 		} else if ( !this.options.useTransition && this.isAnimating ) {
162 | 			this.isAnimating = false;
163 | 			this._execEvent('scrollEnd');
164 | 		}
165 | 
166 | 		this.startX    = this.x;
167 | 		this.startY    = this.y;
168 | 		this.absStartX = this.x;
169 | 		this.absStartY = this.y;
170 | 		this.pointX    = point.pageX;
171 | 		this.pointY    = point.pageY;
172 | 
173 | 		this._execEvent('beforeScrollStart');
174 | 	},
175 | 
176 | 	_move: function (e) {
177 | 		if ( !this.enabled || utils.eventType[e.type] !== this.initiated ) {
178 | 			return;
179 | 		}
180 | 
181 | 		if ( this.options.preventDefault ) {	// increases performance on Android? TODO: check!
182 | 			e.preventDefault();
183 | 		}
184 | 
185 | 		var point		= e.touches ? e.touches[0] : e,
186 | 			deltaX		= point.pageX - this.pointX,
187 | 			deltaY		= point.pageY - this.pointY,
188 | 			timestamp	= utils.getTime(),
189 | 			newX, newY,
190 | 			absDistX, absDistY;
191 | 
192 | 		this.pointX		= point.pageX;
193 | 		this.pointY		= point.pageY;
194 | 
195 | 		this.distX		+= deltaX;
196 | 		this.distY		+= deltaY;
197 | 		absDistX		= Math.abs(this.distX);
198 | 		absDistY		= Math.abs(this.distY);
199 | 
200 | 		// We need to move at least 10 pixels for the scrolling to initiate
201 | 		if ( timestamp - this.endTime > 300 && (absDistX < 10 && absDistY < 10) ) {
202 | 			return;
203 | 		}
204 | 
205 | 		// If you are scrolling in one direction lock the other
206 | 		if ( !this.directionLocked && !this.options.freeScroll ) {
207 | 			if ( absDistX > absDistY + this.options.directionLockThreshold ) {
208 | 				this.directionLocked = 'h';		// lock horizontally
209 | 			} else if ( absDistY >= absDistX + this.options.directionLockThreshold ) {
210 | 				this.directionLocked = 'v';		// lock vertically
211 | 			} else {
212 | 				this.directionLocked = 'n';		// no lock
213 | 			}
214 | 		}
215 | 
216 | 		if ( this.directionLocked == 'h' ) {
217 | 			if ( this.options.eventPassthrough == 'vertical' ) {
218 | 				e.preventDefault();
219 | 			} else if ( this.options.eventPassthrough == 'horizontal' ) {
220 | 				this.initiated = false;
221 | 				return;
222 | 			}
223 | 
224 | 			deltaY = 0;
225 | 		} else if ( this.directionLocked == 'v' ) {
226 | 			if ( this.options.eventPassthrough == 'horizontal' ) {
227 | 				e.preventDefault();
228 | 			} else if ( this.options.eventPassthrough == 'vertical' ) {
229 | 				this.initiated = false;
230 | 				return;
231 | 			}
232 | 
233 | 			deltaX = 0;
234 | 		}
235 | 
236 | 		deltaX = this.hasHorizontalScroll ? deltaX : 0;
237 | 		deltaY = this.hasVerticalScroll ? deltaY : 0;
238 | 
239 | 		newX = this.x + deltaX;
240 | 		newY = this.y + deltaY;
241 | 
242 | 		// Slow down if outside of the boundaries
243 | 		if ( newX > 0 || newX < this.maxScrollX ) {
244 | 			newX = this.options.bounce ? this.x + deltaX / 3 : newX > 0 ? 0 : this.maxScrollX;
245 | 		}
246 | 		if ( newY > 0 || newY < this.maxScrollY ) {
247 | 			newY = this.options.bounce ? this.y + deltaY / 3 : newY > 0 ? 0 : this.maxScrollY;
248 | 		}
249 | 
250 | 		this.directionX = deltaX > 0 ? -1 : deltaX < 0 ? 1 : 0;
251 | 		this.directionY = deltaY > 0 ? -1 : deltaY < 0 ? 1 : 0;
252 | 
253 | 		if ( !this.moved ) {
254 | 			this._execEvent('scrollStart');
255 | 		}
256 | 
257 | 		this.moved = true;
258 | 
259 | 		this._translate(newX, newY);
260 | 
261 | /* REPLACE START: _move */
262 | 
263 | 		if ( timestamp - this.startTime > 300 ) {
264 | 			this.startTime = timestamp;
265 | 			this.startX = this.x;
266 | 			this.startY = this.y;
267 | 		}
268 | 
269 | /* REPLACE END: _move */
270 | 
271 | 	},
272 | 
273 | 	_end: function (e) {
274 | 		if ( !this.enabled || utils.eventType[e.type] !== this.initiated ) {
275 | 			return;
276 | 		}
277 | 
278 | 		if ( this.options.preventDefault && !utils.preventDefaultException(e.target, this.options.preventDefaultException) ) {
279 | 			e.preventDefault();
280 | 		}
281 | 
282 | 		var point = e.changedTouches ? e.changedTouches[0] : e,
283 | 			momentumX,
284 | 			momentumY,
285 | 			duration = utils.getTime() - this.startTime,
286 | 			newX = Math.round(this.x),
287 | 			newY = Math.round(this.y),
288 | 			distanceX = Math.abs(newX - this.startX),
289 | 			distanceY = Math.abs(newY - this.startY),
290 | 			time = 0,
291 | 			easing = '';
292 | 
293 | 		this.isInTransition = 0;
294 | 		this.initiated = 0;
295 | 		this.endTime = utils.getTime();
296 | 
297 | 		// reset if we are outside of the boundaries
298 | 		if ( this.resetPosition(this.options.bounceTime) ) {
299 | 			return;
300 | 		}
301 | 
302 | 		this.scrollTo(newX, newY);	// ensures that the last position is rounded
303 | 
304 | 		// we scrolled less than 10 pixels
305 | 		if ( !this.moved ) {
306 | 			if ( this.options.tap ) {
307 | 				utils.tap(e, this.options.tap);
308 | 			}
309 | 
310 | 			if ( this.options.click ) {
311 | 				utils.click(e);
312 | 			}
313 | 
314 | 			this._execEvent('scrollCancel');
315 | 			return;
316 | 		}
317 | 
318 | 		if ( this._events.flick && duration < 200 && distanceX < 100 && distanceY < 100 ) {
319 | 			this._execEvent('flick');
320 | 			return;
321 | 		}
322 | 
323 | 		// start momentum animation if needed
324 | 		if ( this.options.momentum && duration < 300 ) {
325 | 			momentumX = this.hasHorizontalScroll ? utils.momentum(this.x, this.startX, duration, this.maxScrollX, this.options.bounce ? this.wrapperWidth : 0, this.options.deceleration) : { destination: newX, duration: 0 };
326 | 			momentumY = this.hasVerticalScroll ? utils.momentum(this.y, this.startY, duration, this.maxScrollY, this.options.bounce ? this.wrapperHeight : 0, this.options.deceleration) : { destination: newY, duration: 0 };
327 | 			newX = momentumX.destination;
328 | 			newY = momentumY.destination;
329 | 			time = Math.max(momentumX.duration, momentumY.duration);
330 | 			this.isInTransition = 1;
331 | 		}
332 | 
333 | // INSERT POINT: _end
334 | 
335 | 		if ( newX != this.x || newY != this.y ) {
336 | 			// change easing function when scroller goes out of the boundaries
337 | 			if ( newX > 0 || newX < this.maxScrollX || newY > 0 || newY < this.maxScrollY ) {
338 | 				easing = utils.ease.quadratic;
339 | 			}
340 | 
341 | 			this.scrollTo(newX, newY, time, easing);
342 | 			return;
343 | 		}
344 | 
345 | 		this._execEvent('scrollEnd');
346 | 	},
347 | 
348 | 	_resize: function () {
349 | 		var that = this;
350 | 
351 | 		clearTimeout(this.resizeTimeout);
352 | 
353 | 		this.resizeTimeout = setTimeout(function () {
354 | 			that.refresh();
355 | 		}, this.options.resizePolling);
356 | 	},
357 | 
358 | 	resetPosition: function (time) {
359 | 		var x = this.x,
360 | 			y = this.y;
361 | 
362 | 		time = time || 0;
363 | 
364 | 		if ( !this.hasHorizontalScroll || this.x > 0 ) {
365 | 			x = 0;
366 | 		} else if ( this.x < this.maxScrollX ) {
367 | 			x = this.maxScrollX;
368 | 		}
369 | 
370 | 		if ( !this.hasVerticalScroll || this.y > 0 ) {
371 | 			y = 0;
372 | 		} else if ( this.y < this.maxScrollY ) {
373 | 			y = this.maxScrollY;
374 | 		}
375 | 
376 | 		if ( x == this.x && y == this.y ) {
377 | 			return false;
378 | 		}
379 | 
380 | 		this.scrollTo(x, y, time, this.options.bounceEasing);
381 | 
382 | 		return true;
383 | 	},
384 | 
385 | 	disable: function () {
386 | 		this.enabled = false;
387 | 	},
388 | 
389 | 	enable: function () {
390 | 		this.enabled = true;
391 | 	},
392 | 
393 | 	refresh: function () {
394 | 		utils.getRect(this.wrapper);		// Force reflow
395 | 
396 | 		this.wrapperWidth	= this.wrapper.clientWidth;
397 | 		this.wrapperHeight	= this.wrapper.clientHeight;
398 | 
399 | 		var rect = utils.getRect(this.scroller);
400 | /* REPLACE START: refresh */
401 | 
402 | 		this.scrollerWidth	= rect.width;
403 | 		this.scrollerHeight	= rect.height;
404 | 
405 | 		this.maxScrollX		= this.wrapperWidth - this.scrollerWidth;
406 | 		this.maxScrollY		= this.wrapperHeight - this.scrollerHeight;
407 | 
408 | /* REPLACE END: refresh */
409 | 
410 | 		this.hasHorizontalScroll	= this.options.scrollX && this.maxScrollX < 0;
411 | 		this.hasVerticalScroll		= this.options.scrollY && this.maxScrollY < 0;
412 | 		
413 | 		if ( !this.hasHorizontalScroll ) {
414 | 			this.maxScrollX = 0;
415 | 			this.scrollerWidth = this.wrapperWidth;
416 | 		}
417 | 
418 | 		if ( !this.hasVerticalScroll ) {
419 | 			this.maxScrollY = 0;
420 | 			this.scrollerHeight = this.wrapperHeight;
421 | 		}
422 | 
423 | 		this.endTime = 0;
424 | 		this.directionX = 0;
425 | 		this.directionY = 0;
426 | 		
427 | 		if(utils.hasPointer && !this.options.disablePointer) {
428 | 			// The wrapper should have `touchAction` property for using pointerEvent.
429 | 			this.wrapper.style[utils.style.touchAction] = utils.getTouchAction(this.options.eventPassthrough, true);
430 | 
431 | 			// case. not support 'pinch-zoom'
432 | 			// https://github.com/cubiq/iscroll/issues/1118#issuecomment-270057583
433 | 			if (!this.wrapper.style[utils.style.touchAction]) {
434 | 				this.wrapper.style[utils.style.touchAction] = utils.getTouchAction(this.options.eventPassthrough, false);
435 | 			}
436 | 		}
437 | 		this.wrapperOffset = utils.offset(this.wrapper);
438 | 
439 | 		this._execEvent('refresh');
440 | 
441 | 		this.resetPosition();
442 | 
443 | // INSERT POINT: _refresh
444 | 
445 | 	},	
446 | 
447 | 	on: function (type, fn) {
448 | 		if ( !this._events[type] ) {
449 | 			this._events[type] = [];
450 | 		}
451 | 
452 | 		this._events[type].push(fn);
453 | 	},
454 | 
455 | 	off: function (type, fn) {
456 | 		if ( !this._events[type] ) {
457 | 			return;
458 | 		}
459 | 
460 | 		var index = this._events[type].indexOf(fn);
461 | 
462 | 		if ( index > -1 ) {
463 | 			this._events[type].splice(index, 1);
464 | 		}
465 | 	},
466 | 
467 | 	_execEvent: function (type) {
468 | 		if ( !this._events[type] ) {
469 | 			return;
470 | 		}
471 | 
472 | 		var i = 0,
473 | 			l = this._events[type].length;
474 | 
475 | 		if ( !l ) {
476 | 			return;
477 | 		}
478 | 
479 | 		for ( ; i < l; i++ ) {
480 | 			this._events[type][i].apply(this, [].slice.call(arguments, 1));
481 | 		}
482 | 	},
483 | 
484 | 	scrollBy: function (x, y, time, easing) {
485 | 		x = this.x + x;
486 | 		y = this.y + y;
487 | 		time = time || 0;
488 | 
489 | 		this.scrollTo(x, y, time, easing);
490 | 	},
491 | 
492 | 	scrollTo: function (x, y, time, easing) {
493 | 		easing = easing || utils.ease.circular;
494 | 
495 | 		this.isInTransition = this.options.useTransition && time > 0;
496 | 		var transitionType = this.options.useTransition && easing.style;
497 | 		if ( !time || transitionType ) {
498 | 				if(transitionType) {
499 | 					this._transitionTimingFunction(easing.style);
500 | 					this._transitionTime(time);
501 | 				}
502 | 			this._translate(x, y);
503 | 		} else {
504 | 			this._animate(x, y, time, easing.fn);
505 | 		}
506 | 	},
507 | 
508 | 	scrollToElement: function (el, time, offsetX, offsetY, easing) {
509 | 		el = el.nodeType ? el : this.scroller.querySelector(el);
510 | 
511 | 		if ( !el ) {
512 | 			return;
513 | 		}
514 | 
515 | 		var pos = utils.offset(el);
516 | 
517 | 		pos.left -= this.wrapperOffset.left;
518 | 		pos.top  -= this.wrapperOffset.top;
519 | 
520 | 		// if offsetX/Y are true we center the element to the screen
521 | 		var elRect = utils.getRect(el);
522 | 		var wrapperRect = utils.getRect(this.wrapper);
523 | 		if ( offsetX === true ) {
524 | 			offsetX = Math.round(elRect.width / 2 - wrapperRect.width / 2);
525 | 		}
526 | 		if ( offsetY === true ) {
527 | 			offsetY = Math.round(elRect.height / 2 - wrapperRect.height / 2);
528 | 		}
529 | 
530 | 		pos.left -= offsetX || 0;
531 | 		pos.top  -= offsetY || 0;
532 | 
533 | 		pos.left = pos.left > 0 ? 0 : pos.left < this.maxScrollX ? this.maxScrollX : pos.left;
534 | 		pos.top  = pos.top  > 0 ? 0 : pos.top  < this.maxScrollY ? this.maxScrollY : pos.top;
535 | 
536 | 		time = time === undefined || time === null || time === 'auto' ? Math.max(Math.abs(this.x-pos.left), Math.abs(this.y-pos.top)) : time;
537 | 
538 | 		this.scrollTo(pos.left, pos.top, time, easing);
539 | 	},
540 | 
541 | 	_transitionTime: function (time) {
542 | 		if (!this.options.useTransition) {
543 | 			return;
544 | 		}
545 | 		time = time || 0;
546 | 		var durationProp = utils.style.transitionDuration;
547 | 		if(!durationProp) {
548 | 			return;
549 | 		}
550 | 
551 | 		this.scrollerStyle[durationProp] = time + 'ms';
552 | 
553 | 		if ( !time && utils.isBadAndroid ) {
554 | 			this.scrollerStyle[durationProp] = '0.0001ms';
555 | 			// remove 0.0001ms
556 | 			var self = this;
557 | 			rAF(function() {
558 | 				if(self.scrollerStyle[durationProp] === '0.0001ms') {
559 | 					self.scrollerStyle[durationProp] = '0s';
560 | 				}
561 | 			});
562 | 		}
563 | 
564 | // INSERT POINT: _transitionTime
565 | 
566 | 	},
567 | 
568 | 	_transitionTimingFunction: function (easing) {
569 | 		this.scrollerStyle[utils.style.transitionTimingFunction] = easing;
570 | 
571 | // INSERT POINT: _transitionTimingFunction
572 | 
573 | 	},
574 | 
575 | 	_translate: function (x, y) {
576 | 		if ( this.options.useTransform ) {
577 | 
578 | /* REPLACE START: _translate */
579 | 
580 | 			this.scrollerStyle[utils.style.transform] = 'translate(' + x + 'px,' + y + 'px)' + this.translateZ;
581 | 
582 | /* REPLACE END: _translate */
583 | 
584 | 		} else {
585 | 			x = Math.round(x);
586 | 			y = Math.round(y);
587 | 			this.scrollerStyle.left = x + 'px';
588 | 			this.scrollerStyle.top = y + 'px';
589 | 		}
590 | 
591 | 		this.x = x;
592 | 		this.y = y;
593 | 
594 | // INSERT POINT: _translate
595 | 
596 | 	},
597 | 
598 | 	_initEvents: function (remove) {
599 | 		var eventType = remove ? utils.removeEvent : utils.addEvent,
600 | 			target = this.options.bindToWrapper ? this.wrapper : window;
601 | 
602 | 		eventType(window, 'orientationchange', this);
603 | 		eventType(window, 'resize', this);
604 | 
605 | 		if ( this.options.click ) {
606 | 			eventType(this.wrapper, 'click', this, true);
607 | 		}
608 | 
609 | 		if ( !this.options.disableMouse ) {
610 | 			eventType(this.wrapper, 'mousedown', this);
611 | 			eventType(target, 'mousemove', this);
612 | 			eventType(target, 'mousecancel', this);
613 | 			eventType(target, 'mouseup', this);
614 | 		}
615 | 
616 | 		if ( utils.hasPointer && !this.options.disablePointer ) {
617 | 			eventType(this.wrapper, utils.prefixPointerEvent('pointerdown'), this);
618 | 			eventType(target, utils.prefixPointerEvent('pointermove'), this);
619 | 			eventType(target, utils.prefixPointerEvent('pointercancel'), this);
620 | 			eventType(target, utils.prefixPointerEvent('pointerup'), this);
621 | 		}
622 | 
623 | 		if ( utils.hasTouch && !this.options.disableTouch ) {
624 | 			eventType(this.wrapper, 'touchstart', this);
625 | 			eventType(target, 'touchmove', this);
626 | 			eventType(target, 'touchcancel', this);
627 | 			eventType(target, 'touchend', this);
628 | 		}
629 | 
630 | 		eventType(this.scroller, 'transitionend', this);
631 | 		eventType(this.scroller, 'webkitTransitionEnd', this);
632 | 		eventType(this.scroller, 'oTransitionEnd', this);
633 | 		eventType(this.scroller, 'MSTransitionEnd', this);
634 | 	},
635 | 
636 | 	getComputedPosition: function () {
637 | 		var matrix = window.getComputedStyle(this.scroller, null),
638 | 			x, y;
639 | 
640 | 		if ( this.options.useTransform ) {
641 | 			matrix = matrix[utils.style.transform].split(')')[0].split(', ');
642 | 			x = +(matrix[12] || matrix[4]);
643 | 			y = +(matrix[13] || matrix[5]);
644 | 		} else {
645 | 			x = +matrix.left.replace(/[^-\d.]/g, '');
646 | 			y = +matrix.top.replace(/[^-\d.]/g, '');
647 | 		}
648 | 
649 | 		return { x: x, y: y };
650 | 	},


--------------------------------------------------------------------------------
/src/default/_animate.js:
--------------------------------------------------------------------------------
 1 | 
 2 | 	_animate: function (destX, destY, duration, easingFn) {
 3 | 		var that = this,
 4 | 			startX = this.x,
 5 | 			startY = this.y,
 6 | 			startTime = utils.getTime(),
 7 | 			destTime = startTime + duration;
 8 | 
 9 | 		function step () {
10 | 			var now = utils.getTime(),
11 | 				newX, newY,
12 | 				easing;
13 | 
14 | 			if ( now >= destTime ) {
15 | 				that.isAnimating = false;
16 | 				that._translate(destX, destY);
17 | 
18 | 				if ( !that.resetPosition(that.options.bounceTime) ) {
19 | 					that._execEvent('scrollEnd');
20 | 				}
21 | 
22 | 				return;
23 | 			}
24 | 
25 | 			now = ( now - startTime ) / duration;
26 | 			easing = easingFn(now);
27 | 			newX = ( destX - startX ) * easing + startX;
28 | 			newY = ( destY - startY ) * easing + startY;
29 | 			that._translate(newX, newY);
30 | 
31 | 			if ( that.isAnimating ) {
32 | 				rAF(step);
33 | 			}
34 | 		}
35 | 
36 | 		this.isAnimating = true;
37 | 		step();
38 | 	},


--------------------------------------------------------------------------------
/src/default/handleEvent.js:
--------------------------------------------------------------------------------
 1 | 
 2 | 	handleEvent: function (e) {
 3 | 		switch ( e.type ) {
 4 | 			case 'touchstart':
 5 | 			case 'pointerdown':
 6 | 			case 'MSPointerDown':
 7 | 			case 'mousedown':
 8 | 				this._start(e);
 9 | 				break;
10 | 			case 'touchmove':
11 | 			case 'pointermove':
12 | 			case 'MSPointerMove':
13 | 			case 'mousemove':
14 | 				this._move(e);
15 | 				break;
16 | 			case 'touchend':
17 | 			case 'pointerup':
18 | 			case 'MSPointerUp':
19 | 			case 'mouseup':
20 | 			case 'touchcancel':
21 | 			case 'pointercancel':
22 | 			case 'MSPointerCancel':
23 | 			case 'mousecancel':
24 | 				this._end(e);
25 | 				break;
26 | 			case 'orientationchange':
27 | 			case 'resize':
28 | 				this._resize();
29 | 				break;
30 | 			case 'transitionend':
31 | 			case 'webkitTransitionEnd':
32 | 			case 'oTransitionEnd':
33 | 			case 'MSTransitionEnd':
34 | 				this._transitionEnd(e);
35 | 				break;
36 | 			case 'wheel':
37 | 			case 'DOMMouseScroll':
38 | 			case 'mousewheel':
39 | 				this._wheel(e);
40 | 				break;
41 | 			case 'keydown':
42 | 				this._key(e);
43 | 				break;
44 | 			case 'click':
45 | 				if ( this.enabled && !e._constructed ) {
46 | 					e.preventDefault();
47 | 					e.stopPropagation();
48 | 				}
49 | 				break;
50 | 		}
51 | 	}
52 | };


--------------------------------------------------------------------------------
/src/indicator/_initIndicators.js:
--------------------------------------------------------------------------------
  1 | 
  2 | 	_initIndicators: function () {
  3 | 		var interactive = this.options.interactiveScrollbars,
  4 | 			customStyle = typeof this.options.scrollbars != 'string',
  5 | 			indicators = [],
  6 | 			indicator;
  7 | 
  8 | 		var that = this;
  9 | 
 10 | 		this.indicators = [];
 11 | 
 12 | 		if ( this.options.scrollbars ) {
 13 | 			// Vertical scrollbar
 14 | 			if ( this.options.scrollY ) {
 15 | 				indicator = {
 16 | 					el: createDefaultScrollbar('v', interactive, this.options.scrollbars),
 17 | 					interactive: interactive,
 18 | 					defaultScrollbars: true,
 19 | 					customStyle: customStyle,
 20 | 					resize: this.options.resizeScrollbars,
 21 | 					shrink: this.options.shrinkScrollbars,
 22 | 					fade: this.options.fadeScrollbars,
 23 | 					listenX: false
 24 | 				};
 25 | 
 26 | 				this.wrapper.appendChild(indicator.el);
 27 | 				indicators.push(indicator);
 28 | 			}
 29 | 
 30 | 			// Horizontal scrollbar
 31 | 			if ( this.options.scrollX ) {
 32 | 				indicator = {
 33 | 					el: createDefaultScrollbar('h', interactive, this.options.scrollbars),
 34 | 					interactive: interactive,
 35 | 					defaultScrollbars: true,
 36 | 					customStyle: customStyle,
 37 | 					resize: this.options.resizeScrollbars,
 38 | 					shrink: this.options.shrinkScrollbars,
 39 | 					fade: this.options.fadeScrollbars,
 40 | 					listenY: false
 41 | 				};
 42 | 
 43 | 				this.wrapper.appendChild(indicator.el);
 44 | 				indicators.push(indicator);
 45 | 			}
 46 | 		}
 47 | 
 48 | 		if ( this.options.indicators ) {
 49 | 			// TODO: check concat compatibility
 50 | 			indicators = indicators.concat(this.options.indicators);
 51 | 		}
 52 | 
 53 | 		for ( var i = indicators.length; i--; ) {
 54 | 			this.indicators.push( new Indicator(this, indicators[i]) );
 55 | 		}
 56 | 
 57 | 		// TODO: check if we can use array.map (wide compatibility and performance issues)
 58 | 		function _indicatorsMap (fn) {
 59 | 			if (that.indicators) {
 60 | 				for ( var i = that.indicators.length; i--; ) {
 61 | 					fn.call(that.indicators[i]);
 62 | 				}
 63 | 			}
 64 | 		}
 65 | 
 66 | 		if ( this.options.fadeScrollbars ) {
 67 | 			this.on('scrollEnd', function () {
 68 | 				_indicatorsMap(function () {
 69 | 					this.fade();
 70 | 				});
 71 | 			});
 72 | 
 73 | 			this.on('scrollCancel', function () {
 74 | 				_indicatorsMap(function () {
 75 | 					this.fade();
 76 | 				});
 77 | 			});
 78 | 
 79 | 			this.on('scrollStart', function () {
 80 | 				_indicatorsMap(function () {
 81 | 					this.fade(1);
 82 | 				});
 83 | 			});
 84 | 
 85 | 			this.on('beforeScrollStart', function () {
 86 | 				_indicatorsMap(function () {
 87 | 					this.fade(1, true);
 88 | 				});
 89 | 			});
 90 | 		}
 91 | 
 92 | 
 93 | 		this.on('refresh', function () {
 94 | 			_indicatorsMap(function () {
 95 | 				this.refresh();
 96 | 			});
 97 | 		});
 98 | 
 99 | 		this.on('destroy', function () {
100 | 			_indicatorsMap(function () {
101 | 				this.destroy();
102 | 			});
103 | 
104 | 			delete this.indicators;
105 | 		});
106 | 	},
107 | 


--------------------------------------------------------------------------------
/src/indicator/_transitionTime.js:
--------------------------------------------------------------------------------
1 | 
2 | 		if ( this.indicators ) {
3 | 			for ( var i = this.indicators.length; i--; ) {
4 | 				this.indicators[i].transitionTime(time);
5 | 			}
6 | 		}
7 | 


--------------------------------------------------------------------------------
/src/indicator/_transitionTimingFunction.js:
--------------------------------------------------------------------------------
1 | 
2 | 		if ( this.indicators ) {
3 | 			for ( var i = this.indicators.length; i--; ) {
4 | 				this.indicators[i].transitionTimingFunction(easing);
5 | 			}
6 | 		}
7 | 


--------------------------------------------------------------------------------
/src/indicator/_translate.js:
--------------------------------------------------------------------------------
1 | 
2 | 	if ( this.indicators ) {
3 | 		for ( var i = this.indicators.length; i--; ) {
4 | 			this.indicators[i].updatePosition();
5 | 		}
6 | 	}
7 | 


--------------------------------------------------------------------------------
/src/indicator/build.json:
--------------------------------------------------------------------------------
 1 | {
 2 | 	"insert": {
 3 | 		"OPTIONS": "\t\tresizeScrollbars: true,",
 4 | 		"NORMALIZATION": "\tif ( this.options.shrinkScrollbars == 'scale' ) {\n\t\tthis.options.useTransition = false;\n\t}",
 5 | 		"_init": "\t\tif ( this.options.scrollbars || this.options.indicators ) {\n\t\t\tthis._initIndicators();\n\t\t}",
 6 | 		"_transitionTime": "indicator/_transitionTime.js",
 7 | 		"_transitionTimingFunction": "indicator/_transitionTimingFunction.js",
 8 | 		"_translate": "indicator/_translate.js"
 9 | 	}
10 | }


--------------------------------------------------------------------------------
/src/indicator/indicator.js:
--------------------------------------------------------------------------------
  1 | 
  2 | function createDefaultScrollbar (direction, interactive, type) {
  3 | 	var scrollbar = document.createElement('div'),
  4 | 		indicator = document.createElement('div');
  5 | 
  6 | 	if ( type === true ) {
  7 | 		scrollbar.style.cssText = 'position:absolute;z-index:9999';
  8 | 		indicator.style.cssText = '-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;position:absolute;background:rgba(0,0,0,0.5);border:1px solid rgba(255,255,255,0.9);border-radius:3px';
  9 | 	}
 10 | 
 11 | 	indicator.className = 'iScrollIndicator';
 12 | 
 13 | 	if ( direction == 'h' ) {
 14 | 		if ( type === true ) {
 15 | 			scrollbar.style.cssText += ';height:7px;left:2px;right:2px;bottom:0';
 16 | 			indicator.style.height = '100%';
 17 | 		}
 18 | 		scrollbar.className = 'iScrollHorizontalScrollbar';
 19 | 	} else {
 20 | 		if ( type === true ) {
 21 | 			scrollbar.style.cssText += ';width:7px;bottom:2px;top:2px;right:1px';
 22 | 			indicator.style.width = '100%';
 23 | 		}
 24 | 		scrollbar.className = 'iScrollVerticalScrollbar';
 25 | 	}
 26 | 
 27 | 	scrollbar.style.cssText += ';overflow:hidden';
 28 | 
 29 | 	if ( !interactive ) {
 30 | 		scrollbar.style.pointerEvents = 'none';
 31 | 	}
 32 | 
 33 | 	scrollbar.appendChild(indicator);
 34 | 
 35 | 	return scrollbar;
 36 | }
 37 | 
 38 | function Indicator (scroller, options) {
 39 | 	this.wrapper = typeof options.el == 'string' ? document.querySelector(options.el) : options.el;
 40 | 	this.wrapperStyle = this.wrapper.style;
 41 | 	this.indicator = this.wrapper.children[0];
 42 | 	this.indicatorStyle = this.indicator.style;
 43 | 	this.scroller = scroller;
 44 | 
 45 | 	this.options = {
 46 | 		listenX: true,
 47 | 		listenY: true,
 48 | 		interactive: false,
 49 | 		resize: true,
 50 | 		defaultScrollbars: false,
 51 | 		shrink: false,
 52 | 		fade: false,
 53 | 		speedRatioX: 0,
 54 | 		speedRatioY: 0
 55 | 	};
 56 | 
 57 | 	for ( var i in options ) {
 58 | 		this.options[i] = options[i];
 59 | 	}
 60 | 
 61 | 	this.sizeRatioX = 1;
 62 | 	this.sizeRatioY = 1;
 63 | 	this.maxPosX = 0;
 64 | 	this.maxPosY = 0;
 65 | 
 66 | 	if ( this.options.interactive ) {
 67 | 		if ( !this.options.disableTouch ) {
 68 | 			utils.addEvent(this.indicator, 'touchstart', this);
 69 | 			utils.addEvent(window, 'touchend', this);
 70 | 		}
 71 | 		if ( !this.options.disablePointer ) {
 72 | 			utils.addEvent(this.indicator, utils.prefixPointerEvent('pointerdown'), this);
 73 | 			utils.addEvent(window, utils.prefixPointerEvent('pointerup'), this);
 74 | 		}
 75 | 		if ( !this.options.disableMouse ) {
 76 | 			utils.addEvent(this.indicator, 'mousedown', this);
 77 | 			utils.addEvent(window, 'mouseup', this);
 78 | 		}
 79 | 	}
 80 | 
 81 | 	if ( this.options.fade ) {
 82 | 		this.wrapperStyle[utils.style.transform] = this.scroller.translateZ;
 83 | 		var durationProp = utils.style.transitionDuration;
 84 | 		if(!durationProp) {
 85 | 			return;
 86 | 		}
 87 | 		this.wrapperStyle[durationProp] = utils.isBadAndroid ? '0.0001ms' : '0ms';
 88 | 		// remove 0.0001ms
 89 | 		var self = this;
 90 | 		if(utils.isBadAndroid) {
 91 | 			rAF(function() {
 92 | 				if(self.wrapperStyle[durationProp] === '0.0001ms') {
 93 | 					self.wrapperStyle[durationProp] = '0s';
 94 | 				}
 95 | 			});
 96 | 		}
 97 | 		this.wrapperStyle.opacity = '0';
 98 | 	}
 99 | }
100 | 
101 | Indicator.prototype = {
102 | 	handleEvent: function (e) {
103 | 		switch ( e.type ) {
104 | 			case 'touchstart':
105 | 			case 'pointerdown':
106 | 			case 'MSPointerDown':
107 | 			case 'mousedown':
108 | 				this._start(e);
109 | 				break;
110 | 			case 'touchmove':
111 | 			case 'pointermove':
112 | 			case 'MSPointerMove':
113 | 			case 'mousemove':
114 | 				this._move(e);
115 | 				break;
116 | 			case 'touchend':
117 | 			case 'pointerup':
118 | 			case 'MSPointerUp':
119 | 			case 'mouseup':
120 | 			case 'touchcancel':
121 | 			case 'pointercancel':
122 | 			case 'MSPointerCancel':
123 | 			case 'mousecancel':
124 | 				this._end(e);
125 | 				break;
126 | 		}
127 | 	},
128 | 
129 | 	destroy: function () {
130 | 		if ( this.options.fadeScrollbars ) {
131 | 			clearTimeout(this.fadeTimeout);
132 | 			this.fadeTimeout = null;
133 | 		}
134 | 		if ( this.options.interactive ) {
135 | 			utils.removeEvent(this.indicator, 'touchstart', this);
136 | 			utils.removeEvent(this.indicator, utils.prefixPointerEvent('pointerdown'), this);
137 | 			utils.removeEvent(this.indicator, 'mousedown', this);
138 | 
139 | 			utils.removeEvent(window, 'touchmove', this);
140 | 			utils.removeEvent(window, utils.prefixPointerEvent('pointermove'), this);
141 | 			utils.removeEvent(window, 'mousemove', this);
142 | 
143 | 			utils.removeEvent(window, 'touchend', this);
144 | 			utils.removeEvent(window, utils.prefixPointerEvent('pointerup'), this);
145 | 			utils.removeEvent(window, 'mouseup', this);
146 | 		}
147 | 
148 | 		if ( this.options.defaultScrollbars && this.wrapper.parentNode ) {
149 | 			this.wrapper.parentNode.removeChild(this.wrapper);
150 | 		}
151 | 	},
152 | 
153 | 	_start: function (e) {
154 | 		var point = e.touches ? e.touches[0] : e;
155 | 
156 | 		e.preventDefault();
157 | 		e.stopPropagation();
158 | 
159 | 		this.transitionTime();
160 | 
161 | 		this.initiated = true;
162 | 		this.moved = false;
163 | 		this.lastPointX	= point.pageX;
164 | 		this.lastPointY	= point.pageY;
165 | 
166 | 		this.startTime	= utils.getTime();
167 | 
168 | 		if ( !this.options.disableTouch ) {
169 | 			utils.addEvent(window, 'touchmove', this);
170 | 		}
171 | 		if ( !this.options.disablePointer ) {
172 | 			utils.addEvent(window, utils.prefixPointerEvent('pointermove'), this);
173 | 		}
174 | 		if ( !this.options.disableMouse ) {
175 | 			utils.addEvent(window, 'mousemove', this);
176 | 		}
177 | 
178 | 		this.scroller._execEvent('beforeScrollStart');
179 | 	},
180 | 
181 | 	_move: function (e) {
182 | 		var point = e.touches ? e.touches[0] : e,
183 | 			deltaX, deltaY,
184 | 			newX, newY,
185 | 			timestamp = utils.getTime();
186 | 
187 | 		if ( !this.moved ) {
188 | 			this.scroller._execEvent('scrollStart');
189 | 		}
190 | 
191 | 		this.moved = true;
192 | 
193 | 		deltaX = point.pageX - this.lastPointX;
194 | 		this.lastPointX = point.pageX;
195 | 
196 | 		deltaY = point.pageY - this.lastPointY;
197 | 		this.lastPointY = point.pageY;
198 | 
199 | 		newX = this.x + deltaX;
200 | 		newY = this.y + deltaY;
201 | 
202 | 		this._pos(newX, newY);
203 | 
204 | // INSERT POINT: indicator._move
205 | 
206 | 		e.preventDefault();
207 | 		e.stopPropagation();
208 | 	},
209 | 
210 | 	_end: function (e) {
211 | 		if ( !this.initiated ) {
212 | 			return;
213 | 		}
214 | 
215 | 		this.initiated = false;
216 | 
217 | 		e.preventDefault();
218 | 		e.stopPropagation();
219 | 
220 | 		utils.removeEvent(window, 'touchmove', this);
221 | 		utils.removeEvent(window, utils.prefixPointerEvent('pointermove'), this);
222 | 		utils.removeEvent(window, 'mousemove', this);
223 | 
224 | 		if ( this.scroller.options.snap ) {
225 | 			var snap = this.scroller._nearestSnap(this.scroller.x, this.scroller.y);
226 | 
227 | 			var time = this.options.snapSpeed || Math.max(
228 | 					Math.max(
229 | 						Math.min(Math.abs(this.scroller.x - snap.x), 1000),
230 | 						Math.min(Math.abs(this.scroller.y - snap.y), 1000)
231 | 					), 300);
232 | 
233 | 			if ( this.scroller.x != snap.x || this.scroller.y != snap.y ) {
234 | 				this.scroller.directionX = 0;
235 | 				this.scroller.directionY = 0;
236 | 				this.scroller.currentPage = snap;
237 | 				this.scroller.scrollTo(snap.x, snap.y, time, this.scroller.options.bounceEasing);
238 | 			}
239 | 		}
240 | 
241 | 		if ( this.moved ) {
242 | 			this.scroller._execEvent('scrollEnd');
243 | 		}
244 | 	},
245 | 
246 | 	transitionTime: function (time) {
247 | 		time = time || 0;
248 | 		var durationProp = utils.style.transitionDuration;
249 | 		if(!durationProp) {
250 | 			return;
251 | 		}
252 | 
253 | 		this.indicatorStyle[durationProp] = time + 'ms';
254 | 
255 | 		if ( !time && utils.isBadAndroid ) {
256 | 			this.indicatorStyle[durationProp] = '0.0001ms';
257 | 			// remove 0.0001ms
258 | 			var self = this;
259 | 			rAF(function() {
260 | 				if(self.indicatorStyle[durationProp] === '0.0001ms') {
261 | 					self.indicatorStyle[durationProp] = '0s';
262 | 				}
263 | 			});
264 | 		}
265 | 	},
266 | 
267 | 	transitionTimingFunction: function (easing) {
268 | 		this.indicatorStyle[utils.style.transitionTimingFunction] = easing;
269 | 	},
270 | 
271 | 	refresh: function () {
272 | 		this.transitionTime();
273 | 
274 | 		if ( this.options.listenX && !this.options.listenY ) {
275 | 			this.indicatorStyle.display = this.scroller.hasHorizontalScroll ? 'block' : 'none';
276 | 		} else if ( this.options.listenY && !this.options.listenX ) {
277 | 			this.indicatorStyle.display = this.scroller.hasVerticalScroll ? 'block' : 'none';
278 | 		} else {
279 | 			this.indicatorStyle.display = this.scroller.hasHorizontalScroll || this.scroller.hasVerticalScroll ? 'block' : 'none';
280 | 		}
281 | 
282 | 		if ( this.scroller.hasHorizontalScroll && this.scroller.hasVerticalScroll ) {
283 | 			utils.addClass(this.wrapper, 'iScrollBothScrollbars');
284 | 			utils.removeClass(this.wrapper, 'iScrollLoneScrollbar');
285 | 
286 | 			if ( this.options.defaultScrollbars && this.options.customStyle ) {
287 | 				if ( this.options.listenX ) {
288 | 					this.wrapper.style.right = '8px';
289 | 				} else {
290 | 					this.wrapper.style.bottom = '8px';
291 | 				}
292 | 			}
293 | 		} else {
294 | 			utils.removeClass(this.wrapper, 'iScrollBothScrollbars');
295 | 			utils.addClass(this.wrapper, 'iScrollLoneScrollbar');
296 | 
297 | 			if ( this.options.defaultScrollbars && this.options.customStyle ) {
298 | 				if ( this.options.listenX ) {
299 | 					this.wrapper.style.right = '2px';
300 | 				} else {
301 | 					this.wrapper.style.bottom = '2px';
302 | 				}
303 | 			}
304 | 		}
305 | 
306 | 		utils.getRect(this.wrapper);	// force refresh
307 | 
308 | 		if ( this.options.listenX ) {
309 | 			this.wrapperWidth = this.wrapper.clientWidth;
310 | 			if ( this.options.resize ) {
311 | 				this.indicatorWidth = Math.max(Math.round(this.wrapperWidth * this.wrapperWidth / (this.scroller.scrollerWidth || this.wrapperWidth || 1)), 8);
312 | 				this.indicatorStyle.width = this.indicatorWidth + 'px';
313 | 			} else {
314 | 				this.indicatorWidth = this.indicator.clientWidth;
315 | 			}
316 | 
317 | 			this.maxPosX = this.wrapperWidth - this.indicatorWidth;
318 | 
319 | 			if ( this.options.shrink == 'clip' ) {
320 | 				this.minBoundaryX = -this.indicatorWidth + 8;
321 | 				this.maxBoundaryX = this.wrapperWidth - 8;
322 | 			} else {
323 | 				this.minBoundaryX = 0;
324 | 				this.maxBoundaryX = this.maxPosX;
325 | 			}
326 | 
327 | 			this.sizeRatioX = this.options.speedRatioX || (this.scroller.maxScrollX && (this.maxPosX / this.scroller.maxScrollX));
328 | 		}
329 | 
330 | 		if ( this.options.listenY ) {
331 | 			this.wrapperHeight = this.wrapper.clientHeight;
332 | 			if ( this.options.resize ) {
333 | 				this.indicatorHeight = Math.max(Math.round(this.wrapperHeight * this.wrapperHeight / (this.scroller.scrollerHeight || this.wrapperHeight || 1)), 8);
334 | 				this.indicatorStyle.height = this.indicatorHeight + 'px';
335 | 			} else {
336 | 				this.indicatorHeight = this.indicator.clientHeight;
337 | 			}
338 | 
339 | 			this.maxPosY = this.wrapperHeight - this.indicatorHeight;
340 | 
341 | 			if ( this.options.shrink == 'clip' ) {
342 | 				this.minBoundaryY = -this.indicatorHeight + 8;
343 | 				this.maxBoundaryY = this.wrapperHeight - 8;
344 | 			} else {
345 | 				this.minBoundaryY = 0;
346 | 				this.maxBoundaryY = this.maxPosY;
347 | 			}
348 | 
349 | 			this.maxPosY = this.wrapperHeight - this.indicatorHeight;
350 | 			this.sizeRatioY = this.options.speedRatioY || (this.scroller.maxScrollY && (this.maxPosY / this.scroller.maxScrollY));
351 | 		}
352 | 
353 | 		this.updatePosition();
354 | 	},
355 | 
356 | 	updatePosition: function () {
357 | 		var x = this.options.listenX && Math.round(this.sizeRatioX * this.scroller.x) || 0,
358 | 			y = this.options.listenY && Math.round(this.sizeRatioY * this.scroller.y) || 0;
359 | 
360 | 		if ( !this.options.ignoreBoundaries ) {
361 | 			if ( x < this.minBoundaryX ) {
362 | 				if ( this.options.shrink == 'scale' ) {
363 | 					this.width = Math.max(this.indicatorWidth + x, 8);
364 | 					this.indicatorStyle.width = this.width + 'px';
365 | 				}
366 | 				x = this.minBoundaryX;
367 | 			} else if ( x > this.maxBoundaryX ) {
368 | 				if ( this.options.shrink == 'scale' ) {
369 | 					this.width = Math.max(this.indicatorWidth - (x - this.maxPosX), 8);
370 | 					this.indicatorStyle.width = this.width + 'px';
371 | 					x = this.maxPosX + this.indicatorWidth - this.width;
372 | 				} else {
373 | 					x = this.maxBoundaryX;
374 | 				}
375 | 			} else if ( this.options.shrink == 'scale' && this.width != this.indicatorWidth ) {
376 | 				this.width = this.indicatorWidth;
377 | 				this.indicatorStyle.width = this.width + 'px';
378 | 			}
379 | 
380 | 			if ( y < this.minBoundaryY ) {
381 | 				if ( this.options.shrink == 'scale' ) {
382 | 					this.height = Math.max(this.indicatorHeight + y * 3, 8);
383 | 					this.indicatorStyle.height = this.height + 'px';
384 | 				}
385 | 				y = this.minBoundaryY;
386 | 			} else if ( y > this.maxBoundaryY ) {
387 | 				if ( this.options.shrink == 'scale' ) {
388 | 					this.height = Math.max(this.indicatorHeight - (y - this.maxPosY) * 3, 8);
389 | 					this.indicatorStyle.height = this.height + 'px';
390 | 					y = this.maxPosY + this.indicatorHeight - this.height;
391 | 				} else {
392 | 					y = this.maxBoundaryY;
393 | 				}
394 | 			} else if ( this.options.shrink == 'scale' && this.height != this.indicatorHeight ) {
395 | 				this.height = this.indicatorHeight;
396 | 				this.indicatorStyle.height = this.height + 'px';
397 | 			}
398 | 		}
399 | 
400 | 		this.x = x;
401 | 		this.y = y;
402 | 
403 | 		if ( this.scroller.options.useTransform ) {
404 | 			this.indicatorStyle[utils.style.transform] = 'translate(' + x + 'px,' + y + 'px)' + this.scroller.translateZ;
405 | 		} else {
406 | 			this.indicatorStyle.left = x + 'px';
407 | 			this.indicatorStyle.top = y + 'px';
408 | 		}
409 | 	},
410 | 
411 | 	_pos: function (x, y) {
412 | 		if ( x < 0 ) {
413 | 			x = 0;
414 | 		} else if ( x > this.maxPosX ) {
415 | 			x = this.maxPosX;
416 | 		}
417 | 
418 | 		if ( y < 0 ) {
419 | 			y = 0;
420 | 		} else if ( y > this.maxPosY ) {
421 | 			y = this.maxPosY;
422 | 		}
423 | 
424 | 		x = this.options.listenX ? Math.round(x / this.sizeRatioX) : this.scroller.x;
425 | 		y = this.options.listenY ? Math.round(y / this.sizeRatioY) : this.scroller.y;
426 | 
427 | 		this.scroller.scrollTo(x, y);
428 | 	},
429 | 
430 | 	fade: function (val, hold) {
431 | 		if ( hold && !this.visible ) {
432 | 			return;
433 | 		}
434 | 
435 | 		clearTimeout(this.fadeTimeout);
436 | 		this.fadeTimeout = null;
437 | 
438 | 		var time = val ? 250 : 500,
439 | 			delay = val ? 0 : 300;
440 | 
441 | 		val = val ? '1' : '0';
442 | 
443 | 		this.wrapperStyle[utils.style.transitionDuration] = time + 'ms';
444 | 
445 | 		this.fadeTimeout = setTimeout((function (val) {
446 | 			this.wrapperStyle.opacity = val;
447 | 			this.visible = +val;
448 | 		}).bind(this, val), delay);
449 | 	}
450 | };
451 | 


--------------------------------------------------------------------------------
/src/infinite/build.json:
--------------------------------------------------------------------------------
 1 | {
 2 | 	"insert": {
 3 | 		"OPTIONS": "\t\tinfiniteUseTransform: true,\n\t\tdeceleration: 0.004,",
 4 | 		"NORMALIZATION": "\tif ( this.options.infiniteElements ) {\n\t\tthis.options.probeType = 3;\n\t}\n\tthis.options.infiniteUseTransform = this.options.infiniteUseTransform && this.options.useTransform;",
 5 | 		"_init": "\t\tif ( this.options.infiniteElements ) {\n\t\t\tthis._initInfinite();\n\t\t}"
 6 | 	},
 7 | 	"replace": {
 8 | 		"refresh": "infinite/refresh.js"
 9 | 	}
10 | }


--------------------------------------------------------------------------------
/src/infinite/infinite.js:
--------------------------------------------------------------------------------
 1 | 
 2 | 	_initInfinite: function () {
 3 | 		var el = this.options.infiniteElements;
 4 | 
 5 | 		this.infiniteElements = typeof el == 'string' ? document.querySelectorAll(el) : el;
 6 | 		this.infiniteLength = this.infiniteElements.length;
 7 | 		this.infiniteMaster = this.infiniteElements[0];
 8 | 		this.infiniteElementHeight = utils.getRect(this.infiniteMaster).height;
 9 | 		this.infiniteHeight = this.infiniteLength * this.infiniteElementHeight;
10 | 
11 | 		this.options.cacheSize = this.options.cacheSize || 1000;
12 | 		this.infiniteCacheBuffer = Math.round(this.options.cacheSize / 4);
13 | 
14 | 		//this.infiniteCache = {};
15 | 		this.options.dataset.call(this, 0, this.options.cacheSize);
16 | 
17 | 		this.on('refresh', function () {
18 | 			var elementsPerPage = Math.ceil(this.wrapperHeight / this.infiniteElementHeight);
19 | 			this.infiniteUpperBufferSize = Math.floor((this.infiniteLength - elementsPerPage) / 2);
20 | 			this.reorderInfinite();
21 | 		});
22 | 
23 | 		this.on('scroll', this.reorderInfinite);
24 | 	},
25 | 
26 | 	// TO-DO: clean up the mess
27 | 	reorderInfinite: function () {
28 | 		var center = -this.y + this.wrapperHeight / 2;
29 | 
30 | 		var minorPhase = Math.max(Math.floor(-this.y / this.infiniteElementHeight) - this.infiniteUpperBufferSize, 0),
31 | 			majorPhase = Math.floor(minorPhase / this.infiniteLength),
32 | 			phase = minorPhase - majorPhase * this.infiniteLength;
33 | 
34 | 		var top = 0;
35 | 		var i = 0;
36 | 		var update = [];
37 | 
38 | 		//var cachePhase = Math.floor((minorPhase + this.infiniteLength / 2) / this.infiniteCacheBuffer);
39 | 		var cachePhase = Math.floor(minorPhase / this.infiniteCacheBuffer);
40 | 
41 | 		while ( i < this.infiniteLength ) {
42 | 			top = i * this.infiniteElementHeight + majorPhase * this.infiniteHeight;
43 | 
44 | 			if ( phase > i ) {
45 | 				top += this.infiniteElementHeight * this.infiniteLength;
46 | 			}
47 | 
48 | 			if ( this.infiniteElements[i]._top !== top ) {
49 | 				this.infiniteElements[i]._phase = top / this.infiniteElementHeight;
50 | 
51 | 				if ( this.infiniteElements[i]._phase < this.options.infiniteLimit ) {
52 | 					this.infiniteElements[i]._top = top;
53 | 					if ( this.options.infiniteUseTransform ) {
54 | 						this.infiniteElements[i].style[utils.style.transform] = 'translate(0, ' + top + 'px)' + this.translateZ;
55 | 					} else {
56 | 						this.infiniteElements[i].style.top = top + 'px';
57 | 					}
58 | 					update.push(this.infiniteElements[i]);
59 | 				}
60 | 			}
61 | 
62 | 			i++;
63 | 		}
64 | 
65 | 		if ( this.cachePhase != cachePhase && (cachePhase === 0 || minorPhase - this.infiniteCacheBuffer > 0) ) {
66 | 			this.options.dataset.call(this, Math.max(cachePhase * this.infiniteCacheBuffer - this.infiniteCacheBuffer, 0), this.options.cacheSize);
67 | 		}
68 | 
69 | 		this.cachePhase = cachePhase;
70 | 
71 | 		this.updateContent(update);
72 | 	},
73 | 
74 | 	updateContent: function (els) {
75 | 		if ( this.infiniteCache === undefined ) {
76 | 			return;
77 | 		}
78 | 
79 | 		for ( var i = 0, l = els.length; i < l; i++ ) {
80 | 			this.options.dataFiller.call(this, els[i], this.infiniteCache[els[i]._phase]);
81 | 		}
82 | 	},
83 | 
84 | 	updateCache: function (start, data) {
85 | 		var firstRun = this.infiniteCache === undefined;
86 | 
87 | 		this.infiniteCache = {};
88 | 
89 | 		for ( var i = 0, l = data.length; i < l; i++ ) {
90 | 			this.infiniteCache[start++] = data[i];
91 | 		}
92 | 
93 | 		if ( firstRun ) {
94 | 			this.updateContent(this.infiniteElements);
95 | 		}
96 | 
97 | 	},
98 | 
99 | 


--------------------------------------------------------------------------------
/src/infinite/refresh.js:
--------------------------------------------------------------------------------
 1 | 
 2 | 		this.scrollerWidth	= rect.width;
 3 | 		this.scrollerHeight	= rect.height;
 4 | 
 5 | 		this.maxScrollX		= this.wrapperWidth - this.scrollerWidth;
 6 | 
 7 | 		var limit;
 8 | 		if ( this.options.infiniteElements ) {
 9 | 			this.options.infiniteLimit = this.options.infiniteLimit || Math.floor(2147483645 / this.infiniteElementHeight);
10 | 			limit = -this.options.infiniteLimit * this.infiniteElementHeight + this.wrapperHeight;
11 | 		}
12 | 		this.maxScrollY		= limit !== undefined ? limit : this.wrapperHeight - this.scrollerHeight;
13 | 


--------------------------------------------------------------------------------
/src/keys/build.json:
--------------------------------------------------------------------------------
1 | {
2 | 	"insert": {
3 | 		"_init": "\t\tif ( this.options.keyBindings ) {\n\t\t\tthis._initKeys();\n\t\t}"
4 | 	}
5 | }


--------------------------------------------------------------------------------
/src/keys/keys.js:
--------------------------------------------------------------------------------
  1 | 
  2 | 	_initKeys: function (e) {
  3 | 		// default key bindings
  4 | 		var keys = {
  5 | 			pageUp: 33,
  6 | 			pageDown: 34,
  7 | 			end: 35,
  8 | 			home: 36,
  9 | 			left: 37,
 10 | 			up: 38,
 11 | 			right: 39,
 12 | 			down: 40
 13 | 		};
 14 | 		var i;
 15 | 
 16 | 		// if you give me characters I give you keycode
 17 | 		if ( typeof this.options.keyBindings == 'object' ) {
 18 | 			for ( i in this.options.keyBindings ) {
 19 | 				if ( typeof this.options.keyBindings[i] == 'string' ) {
 20 | 					this.options.keyBindings[i] = this.options.keyBindings[i].toUpperCase().charCodeAt(0);
 21 | 				}
 22 | 			}
 23 | 		} else {
 24 | 			this.options.keyBindings = {};
 25 | 		}
 26 | 
 27 | 		for ( i in keys ) {
 28 | 			this.options.keyBindings[i] = this.options.keyBindings[i] || keys[i];
 29 | 		}
 30 | 
 31 | 		utils.addEvent(window, 'keydown', this);
 32 | 
 33 | 		this.on('destroy', function () {
 34 | 			utils.removeEvent(window, 'keydown', this);
 35 | 		});
 36 | 	},
 37 | 
 38 | 	_key: function (e) {
 39 | 		if ( !this.enabled ) {
 40 | 			return;
 41 | 		}
 42 | 
 43 | 		var snap = this.options.snap,	// we are using this alot, better to cache it
 44 | 			newX = snap ? this.currentPage.pageX : this.x,
 45 | 			newY = snap ? this.currentPage.pageY : this.y,
 46 | 			now = utils.getTime(),
 47 | 			prevTime = this.keyTime || 0,
 48 | 			acceleration = 0.250,
 49 | 			pos;
 50 | 
 51 | 		if ( this.options.useTransition && this.isInTransition ) {
 52 | 			pos = this.getComputedPosition();
 53 | 
 54 | 			this._translate(Math.round(pos.x), Math.round(pos.y));
 55 | 			this.isInTransition = false;
 56 | 		}
 57 | 
 58 | 		this.keyAcceleration = now - prevTime < 200 ? Math.min(this.keyAcceleration + acceleration, 50) : 0;
 59 | 
 60 | 		switch ( e.keyCode ) {
 61 | 			case this.options.keyBindings.pageUp:
 62 | 				if ( this.hasHorizontalScroll && !this.hasVerticalScroll ) {
 63 | 					newX += snap ? 1 : this.wrapperWidth;
 64 | 				} else {
 65 | 					newY += snap ? 1 : this.wrapperHeight;
 66 | 				}
 67 | 				break;
 68 | 			case this.options.keyBindings.pageDown:
 69 | 				if ( this.hasHorizontalScroll && !this.hasVerticalScroll ) {
 70 | 					newX -= snap ? 1 : this.wrapperWidth;
 71 | 				} else {
 72 | 					newY -= snap ? 1 : this.wrapperHeight;
 73 | 				}
 74 | 				break;
 75 | 			case this.options.keyBindings.end:
 76 | 				newX = snap ? this.pages.length-1 : this.maxScrollX;
 77 | 				newY = snap ? this.pages[0].length-1 : this.maxScrollY;
 78 | 				break;
 79 | 			case this.options.keyBindings.home:
 80 | 				newX = 0;
 81 | 				newY = 0;
 82 | 				break;
 83 | 			case this.options.keyBindings.left:
 84 | 				newX += snap ? -1 : 5 + this.keyAcceleration>>0;
 85 | 				break;
 86 | 			case this.options.keyBindings.up:
 87 | 				newY += snap ? 1 : 5 + this.keyAcceleration>>0;
 88 | 				break;
 89 | 			case this.options.keyBindings.right:
 90 | 				newX -= snap ? -1 : 5 + this.keyAcceleration>>0;
 91 | 				break;
 92 | 			case this.options.keyBindings.down:
 93 | 				newY -= snap ? 1 : 5 + this.keyAcceleration>>0;
 94 | 				break;
 95 | 			default:
 96 | 				return;
 97 | 		}
 98 | 
 99 | 		if ( snap ) {
100 | 			this.goToPage(newX, newY);
101 | 			return;
102 | 		}
103 | 
104 | 		if ( newX > 0 ) {
105 | 			newX = 0;
106 | 			this.keyAcceleration = 0;
107 | 		} else if ( newX < this.maxScrollX ) {
108 | 			newX = this.maxScrollX;
109 | 			this.keyAcceleration = 0;
110 | 		}
111 | 
112 | 		if ( newY > 0 ) {
113 | 			newY = 0;
114 | 			this.keyAcceleration = 0;
115 | 		} else if ( newY < this.maxScrollY ) {
116 | 			newY = this.maxScrollY;
117 | 			this.keyAcceleration = 0;
118 | 		}
119 | 
120 | 		this.scrollTo(newX, newY, 0);
121 | 
122 | 		this.keyTime = now;
123 | 	},
124 | 


--------------------------------------------------------------------------------
/src/open.js:
--------------------------------------------------------------------------------
1 | (function (window, document, Math) {
2 | 


--------------------------------------------------------------------------------
/src/probe/_animate.js:
--------------------------------------------------------------------------------
 1 | 
 2 | 	_animate: function (destX, destY, duration, easingFn) {
 3 | 		var that = this,
 4 | 			startX = this.x,
 5 | 			startY = this.y,
 6 | 			startTime = utils.getTime(),
 7 | 			destTime = startTime + duration;
 8 | 
 9 | 		function step () {
10 | 			var now = utils.getTime(),
11 | 				newX, newY,
12 | 				easing;
13 | 
14 | 			if ( now >= destTime ) {
15 | 				that.isAnimating = false;
16 | 				that._translate(destX, destY);
17 | 				
18 | 				if ( !that.resetPosition(that.options.bounceTime) ) {
19 | 					that._execEvent('scrollEnd');
20 | 				}
21 | 
22 | 				return;
23 | 			}
24 | 
25 | 			now = ( now - startTime ) / duration;
26 | 			easing = easingFn(now);
27 | 			newX = ( destX - startX ) * easing + startX;
28 | 			newY = ( destY - startY ) * easing + startY;
29 | 			that._translate(newX, newY);
30 | 
31 | 			if ( that.isAnimating ) {
32 | 				rAF(step);
33 | 			}
34 | 
35 | 			if ( that.options.probeType == 3 ) {
36 | 				that._execEvent('scroll');
37 | 			}
38 | 		}
39 | 
40 | 		this.isAnimating = true;
41 | 		step();
42 | 	},
43 | 


--------------------------------------------------------------------------------
/src/probe/_move.js:
--------------------------------------------------------------------------------
 1 | 
 2 | 		if ( timestamp - this.startTime > 300 ) {
 3 | 			this.startTime = timestamp;
 4 | 			this.startX = this.x;
 5 | 			this.startY = this.y;
 6 | 
 7 | 			if ( this.options.probeType == 1 ) {
 8 | 				this._execEvent('scroll');
 9 | 			}
10 | 		}
11 | 
12 | 		if ( this.options.probeType > 1 ) {
13 | 			this._execEvent('scroll');
14 | 		}
15 | 


--------------------------------------------------------------------------------
/src/probe/build.json:
--------------------------------------------------------------------------------
 1 | {
 2 | 	"insert": {
 3 | 		"NORMALIZATION": "\tif ( this.options.probeType == 3 ) {\n\t\tthis.options.useTransition = false;\t}",
 4 | 		"_wheel": "\t\tif ( this.options.probeType > 1 ) {\n\t\t\tthis._execEvent('scroll');\n\t\t}",
 5 | 		"indicator._move": "probe/indicator._move.js"
 6 | 	},
 7 | 	"replace": {
 8 | 		"_move": "probe/_move.js"
 9 | 	}
10 | }


--------------------------------------------------------------------------------
/src/probe/indicator._move.js:
--------------------------------------------------------------------------------
1 | 
2 | 		if ( this.scroller.options.probeType == 1 && timestamp - this.startTime > 300 ) {
3 | 			this.startTime = timestamp;
4 | 			this.scroller._execEvent('scroll');
5 | 		} else if ( this.scroller.options.probeType > 1 ) {
6 | 			this.scroller._execEvent('scroll');
7 | 		}
8 | 


--------------------------------------------------------------------------------
/src/probe/probe.js:
--------------------------------------------------------------------------------
1 | 
2 | iScroll.prototype._initProbe = function () {
3 | 	if ( this.options.probeType == 3 ) {
4 | 		this.options.useTransition = false;
5 | 	}
6 | };
7 | 


--------------------------------------------------------------------------------
/src/snap/_end.js:
--------------------------------------------------------------------------------
 1 | 
 2 | 		if ( this.options.snap ) {
 3 | 			var snap = this._nearestSnap(newX, newY);
 4 | 			this.currentPage = snap;
 5 | 			time = this.options.snapSpeed || Math.max(
 6 | 					Math.max(
 7 | 						Math.min(Math.abs(newX - snap.x), 1000),
 8 | 						Math.min(Math.abs(newY - snap.y), 1000)
 9 | 					), 300);
10 | 			newX = snap.x;
11 | 			newY = snap.y;
12 | 
13 | 			this.directionX = 0;
14 | 			this.directionY = 0;
15 | 			easing = this.options.bounceEasing;
16 | 		}


--------------------------------------------------------------------------------
/src/snap/build.json:
--------------------------------------------------------------------------------
1 | {
2 | 	"insert": {
3 | 		"OPTIONS": "\t\tsnapThreshold: 0.334,",
4 | 		"_end": "snap/_end.js",
5 | 		"refresh": "snap/refresh.js",
6 | 		"_init": "\t\tif ( this.options.snap ) {\n\t\t\tthis._initSnap();\n\t\t}"
7 | 	}
8 | }


--------------------------------------------------------------------------------
/src/snap/refresh.js:
--------------------------------------------------------------------------------
 1 | 
 2 | 		if ( this.options.snap ) {
 3 | 			var snap = this._nearestSnap(this.x, this.y);
 4 | 			if ( this.x == snap.x && this.y == snap.y ) {
 5 | 				return;
 6 | 			}
 7 | 
 8 | 			this.currentPage = snap;
 9 | 			this.scrollTo(snap.x, snap.y);
10 | 		}
11 | 


--------------------------------------------------------------------------------
/src/snap/snap.js:
--------------------------------------------------------------------------------
  1 | 
  2 | 	_initSnap: function () {
  3 | 		this.currentPage = {};
  4 | 
  5 | 		if ( typeof this.options.snap == 'string' ) {
  6 | 			this.options.snap = this.scroller.querySelectorAll(this.options.snap);
  7 | 		}
  8 | 
  9 | 		this.on('refresh', function () {
 10 | 			var i = 0, l,
 11 | 				m = 0, n,
 12 | 				cx, cy,
 13 | 				x = 0, y,
 14 | 				stepX = this.options.snapStepX || this.wrapperWidth,
 15 | 				stepY = this.options.snapStepY || this.wrapperHeight,
 16 | 				el,
 17 | 				rect;
 18 | 
 19 | 			this.pages = [];
 20 | 
 21 | 			if ( !this.wrapperWidth || !this.wrapperHeight || !this.scrollerWidth || !this.scrollerHeight ) {
 22 | 				return;
 23 | 			}
 24 | 
 25 | 			if ( this.options.snap === true ) {
 26 | 				cx = Math.round( stepX / 2 );
 27 | 				cy = Math.round( stepY / 2 );
 28 | 
 29 | 				while ( x > -this.scrollerWidth ) {
 30 | 					this.pages[i] = [];
 31 | 					l = 0;
 32 | 					y = 0;
 33 | 
 34 | 					while ( y > -this.scrollerHeight ) {
 35 | 						this.pages[i][l] = {
 36 | 							x: Math.max(x, this.maxScrollX),
 37 | 							y: Math.max(y, this.maxScrollY),
 38 | 							width: stepX,
 39 | 							height: stepY,
 40 | 							cx: x - cx,
 41 | 							cy: y - cy
 42 | 						};
 43 | 
 44 | 						y -= stepY;
 45 | 						l++;
 46 | 					}
 47 | 
 48 | 					x -= stepX;
 49 | 					i++;
 50 | 				}
 51 | 			} else {
 52 | 				el = this.options.snap;
 53 | 				l = el.length;
 54 | 				n = -1;
 55 | 
 56 | 				for ( ; i < l; i++ ) {
 57 | 					rect = utils.getRect(el[i]);
 58 | 					if ( i === 0 || rect.left <= utils.getRect(el[i-1]).left ) {
 59 | 						m = 0;
 60 | 						n++;
 61 | 					}
 62 | 
 63 | 					if ( !this.pages[m] ) {
 64 | 						this.pages[m] = [];
 65 | 					}
 66 | 
 67 | 					x = Math.max(-rect.left, this.maxScrollX);
 68 | 					y = Math.max(-rect.top, this.maxScrollY);
 69 | 					cx = x - Math.round(rect.width / 2);
 70 | 					cy = y - Math.round(rect.height / 2);
 71 | 
 72 | 					this.pages[m][n] = {
 73 | 						x: x,
 74 | 						y: y,
 75 | 						width: rect.width,
 76 | 						height: rect.height,
 77 | 						cx: cx,
 78 | 						cy: cy
 79 | 					};
 80 | 
 81 | 					if ( x > this.maxScrollX ) {
 82 | 						m++;
 83 | 					}
 84 | 				}
 85 | 			}
 86 | 
 87 | 			this.goToPage(this.currentPage.pageX || 0, this.currentPage.pageY || 0, 0);
 88 | 
 89 | 			// Update snap threshold if needed
 90 | 			if ( this.options.snapThreshold % 1 === 0 ) {
 91 | 				this.snapThresholdX = this.options.snapThreshold;
 92 | 				this.snapThresholdY = this.options.snapThreshold;
 93 | 			} else {
 94 | 				this.snapThresholdX = Math.round(this.pages[this.currentPage.pageX][this.currentPage.pageY].width * this.options.snapThreshold);
 95 | 				this.snapThresholdY = Math.round(this.pages[this.currentPage.pageX][this.currentPage.pageY].height * this.options.snapThreshold);
 96 | 			}
 97 | 		});
 98 | 
 99 | 		this.on('flick', function () {
100 | 			var time = this.options.snapSpeed || Math.max(
101 | 					Math.max(
102 | 						Math.min(Math.abs(this.x - this.startX), 1000),
103 | 						Math.min(Math.abs(this.y - this.startY), 1000)
104 | 					), 300);
105 | 
106 | 			this.goToPage(
107 | 				this.currentPage.pageX + this.directionX,
108 | 				this.currentPage.pageY + this.directionY,
109 | 				time
110 | 			);
111 | 		});
112 | 	},
113 | 
114 | 	_nearestSnap: function (x, y) {
115 | 		if ( !this.pages.length ) {
116 | 			return { x: 0, y: 0, pageX: 0, pageY: 0 };
117 | 		}
118 | 
119 | 		var i = 0,
120 | 			l = this.pages.length,
121 | 			m = 0;
122 | 
123 | 		// Check if we exceeded the snap threshold
124 | 		if ( Math.abs(x - this.absStartX) < this.snapThresholdX &&
125 | 			Math.abs(y - this.absStartY) < this.snapThresholdY ) {
126 | 			return this.currentPage;
127 | 		}
128 | 
129 | 		if ( x > 0 ) {
130 | 			x = 0;
131 | 		} else if ( x < this.maxScrollX ) {
132 | 			x = this.maxScrollX;
133 | 		}
134 | 
135 | 		if ( y > 0 ) {
136 | 			y = 0;
137 | 		} else if ( y < this.maxScrollY ) {
138 | 			y = this.maxScrollY;
139 | 		}
140 | 
141 | 		for ( ; i < l; i++ ) {
142 | 			if ( x >= this.pages[i][0].cx ) {
143 | 				x = this.pages[i][0].x;
144 | 				break;
145 | 			}
146 | 		}
147 | 
148 | 		l = this.pages[i].length;
149 | 
150 | 		for ( ; m < l; m++ ) {
151 | 			if ( y >= this.pages[0][m].cy ) {
152 | 				y = this.pages[0][m].y;
153 | 				break;
154 | 			}
155 | 		}
156 | 
157 | 		if ( i == this.currentPage.pageX ) {
158 | 			i += this.directionX;
159 | 
160 | 			if ( i < 0 ) {
161 | 				i = 0;
162 | 			} else if ( i >= this.pages.length ) {
163 | 				i = this.pages.length - 1;
164 | 			}
165 | 
166 | 			x = this.pages[i][0].x;
167 | 		}
168 | 
169 | 		if ( m == this.currentPage.pageY ) {
170 | 			m += this.directionY;
171 | 
172 | 			if ( m < 0 ) {
173 | 				m = 0;
174 | 			} else if ( m >= this.pages[0].length ) {
175 | 				m = this.pages[0].length - 1;
176 | 			}
177 | 
178 | 			y = this.pages[0][m].y;
179 | 		}
180 | 
181 | 		return {
182 | 			x: x,
183 | 			y: y,
184 | 			pageX: i,
185 | 			pageY: m
186 | 		};
187 | 	},
188 | 
189 | 	goToPage: function (x, y, time, easing) {
190 | 		easing = easing || this.options.bounceEasing;
191 | 
192 | 		if ( x >= this.pages.length ) {
193 | 			x = this.pages.length - 1;
194 | 		} else if ( x < 0 ) {
195 | 			x = 0;
196 | 		}
197 | 
198 | 		if ( y >= this.pages[x].length ) {
199 | 			y = this.pages[x].length - 1;
200 | 		} else if ( y < 0 ) {
201 | 			y = 0;
202 | 		}
203 | 
204 | 		var posX = this.pages[x][y].x,
205 | 			posY = this.pages[x][y].y;
206 | 
207 | 		time = time === undefined ? this.options.snapSpeed || Math.max(
208 | 			Math.max(
209 | 				Math.min(Math.abs(posX - this.x), 1000),
210 | 				Math.min(Math.abs(posY - this.y), 1000)
211 | 			), 300) : time;
212 | 
213 | 		this.currentPage = {
214 | 			x: posX,
215 | 			y: posY,
216 | 			pageX: x,
217 | 			pageY: y
218 | 		};
219 | 
220 | 		this.scrollTo(posX, posY, time, easing);
221 | 	},
222 | 
223 | 	next: function (time, easing) {
224 | 		var x = this.currentPage.pageX,
225 | 			y = this.currentPage.pageY;
226 | 
227 | 		x++;
228 | 
229 | 		if ( x >= this.pages.length && this.hasVerticalScroll ) {
230 | 			x = 0;
231 | 			y++;
232 | 		}
233 | 
234 | 		this.goToPage(x, y, time, easing);
235 | 	},
236 | 
237 | 	prev: function (time, easing) {
238 | 		var x = this.currentPage.pageX,
239 | 			y = this.currentPage.pageY;
240 | 
241 | 		x--;
242 | 
243 | 		if ( x < 0 && this.hasVerticalScroll ) {
244 | 			x = 0;
245 | 			y--;
246 | 		}
247 | 
248 | 		this.goToPage(x, y, time, easing);
249 | 	},
250 | 


--------------------------------------------------------------------------------
/src/utils.js:
--------------------------------------------------------------------------------
  1 | var rAF = window.requestAnimationFrame	||
  2 | 	window.webkitRequestAnimationFrame	||
  3 | 	window.mozRequestAnimationFrame		||
  4 | 	window.oRequestAnimationFrame		||
  5 | 	window.msRequestAnimationFrame		||
  6 | 	function (callback) { window.setTimeout(callback, 1000 / 60); };
  7 | 
  8 | var utils = (function () {
  9 | 	var me = {};
 10 | 
 11 | 	var _elementStyle = document.createElement('div').style;
 12 | 	var _vendor = (function () {
 13 | 		var vendors = ['t', 'webkitT', 'MozT', 'msT', 'OT'],
 14 | 			transform,
 15 | 			i = 0,
 16 | 			l = vendors.length;
 17 | 
 18 | 		for ( ; i < l; i++ ) {
 19 | 			transform = vendors[i] + 'ransform';
 20 | 			if ( transform in _elementStyle ) return vendors[i].substr(0, vendors[i].length-1);
 21 | 		}
 22 | 
 23 | 		return false;
 24 | 	})();
 25 | 
 26 | 	function _prefixStyle (style) {
 27 | 		if ( _vendor === false ) return false;
 28 | 		if ( _vendor === '' ) return style;
 29 | 		return _vendor + style.charAt(0).toUpperCase() + style.substr(1);
 30 | 	}
 31 | 
 32 | 	me.getTime = Date.now || function getTime () { return new Date().getTime(); };
 33 | 
 34 | 	me.extend = function (target, obj) {
 35 | 		for ( var i in obj ) {
 36 | 			target[i] = obj[i];
 37 | 		}
 38 | 	};
 39 | 
 40 | 	me.addEvent = function (el, type, fn, capture) {
 41 | 		el.addEventListener(type, fn, !!capture);
 42 | 	};
 43 | 
 44 | 	me.removeEvent = function (el, type, fn, capture) {
 45 | 		el.removeEventListener(type, fn, !!capture);
 46 | 	};
 47 | 
 48 | 	me.prefixPointerEvent = function (pointerEvent) {
 49 | 		return window.MSPointerEvent ?
 50 | 			'MSPointer' + pointerEvent.charAt(7).toUpperCase() + pointerEvent.substr(8):
 51 | 			pointerEvent;
 52 | 	};
 53 | 
 54 | 	me.momentum = function (current, start, time, lowerMargin, wrapperSize, deceleration) {
 55 | 		var distance = current - start,
 56 | 			speed = Math.abs(distance) / time,
 57 | 			destination,
 58 | 			duration;
 59 | 
 60 | 		deceleration = deceleration === undefined ? 0.0006 : deceleration;
 61 | 
 62 | 		destination = current + ( speed * speed ) / ( 2 * deceleration ) * ( distance < 0 ? -1 : 1 );
 63 | 		duration = speed / deceleration;
 64 | 
 65 | 		if ( destination < lowerMargin ) {
 66 | 			destination = wrapperSize ? lowerMargin - ( wrapperSize / 2.5 * ( speed / 8 ) ) : lowerMargin;
 67 | 			distance = Math.abs(destination - current);
 68 | 			duration = distance / speed;
 69 | 		} else if ( destination > 0 ) {
 70 | 			destination = wrapperSize ? wrapperSize / 2.5 * ( speed / 8 ) : 0;
 71 | 			distance = Math.abs(current) + destination;
 72 | 			duration = distance / speed;
 73 | 		}
 74 | 
 75 | 		return {
 76 | 			destination: Math.round(destination),
 77 | 			duration: duration
 78 | 		};
 79 | 	};
 80 | 
 81 | 	var _transform = _prefixStyle('transform');
 82 | 
 83 | 	me.extend(me, {
 84 | 		hasTransform: _transform !== false,
 85 | 		hasPerspective: _prefixStyle('perspective') in _elementStyle,
 86 | 		hasTouch: 'ontouchstart' in window,
 87 | 		hasPointer: !!(window.PointerEvent || window.MSPointerEvent), // IE10 is prefixed
 88 | 		hasTransition: _prefixStyle('transition') in _elementStyle
 89 | 	});
 90 | 
 91 | 	/*
 92 | 	This should find all Android browsers lower than build 535.19 (both stock browser and webview)
 93 | 	- galaxy S2 is ok
 94 |     - 2.3.6 : `AppleWebKit/533.1 (KHTML, like Gecko) Version/4.0 Mobile Safari/533.1`
 95 |     - 4.0.4 : `AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0 Mobile Safari/534.30`
 96 |    - galaxy S3 is badAndroid (stock brower, webview)
 97 |      `AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0 Mobile Safari/534.30`
 98 |    - galaxy S4 is badAndroid (stock brower, webview)
 99 |      `AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0 Mobile Safari/534.30`
100 |    - galaxy S5 is OK
101 |      `AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Mobile Safari/537.36 (Chrome/)`
102 |    - galaxy S6 is OK
103 |      `AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Mobile Safari/537.36 (Chrome/)`
104 |   */
105 | 	me.isBadAndroid = (function() {
106 | 		var appVersion = window.navigator.appVersion;
107 | 		// Android browser is not a chrome browser.
108 | 		if (/Android/.test(appVersion) && !(/Chrome\/\d/.test(appVersion))) {
109 | 			var safariVersion = appVersion.match(/Safari\/(\d+.\d)/);
110 | 			if(safariVersion && typeof safariVersion === "object" && safariVersion.length >= 2) {
111 | 				return parseFloat(safariVersion[1]) < 535.19;
112 | 			} else {
113 | 				return true;
114 | 			}
115 | 		} else {
116 | 			return false;
117 | 		}
118 | 	})();
119 | 
120 | 	me.extend(me.style = {}, {
121 | 		transform: _transform,
122 | 		transitionTimingFunction: _prefixStyle('transitionTimingFunction'),
123 | 		transitionDuration: _prefixStyle('transitionDuration'),
124 | 		transitionDelay: _prefixStyle('transitionDelay'),
125 | 		transformOrigin: _prefixStyle('transformOrigin'),
126 | 		touchAction: _prefixStyle('touchAction')
127 | 	});
128 | 
129 | 	me.hasClass = function (e, c) {
130 | 		var re = new RegExp("(^|\\s)" + c + "(\\s|$)");
131 | 		return re.test(e.className);
132 | 	};
133 | 
134 | 	me.addClass = function (e, c) {
135 | 		if ( me.hasClass(e, c) ) {
136 | 			return;
137 | 		}
138 | 
139 | 		var newclass = e.className.split(' ');
140 | 		newclass.push(c);
141 | 		e.className = newclass.join(' ');
142 | 	};
143 | 
144 | 	me.removeClass = function (e, c) {
145 | 		if ( !me.hasClass(e, c) ) {
146 | 			return;
147 | 		}
148 | 
149 | 		var re = new RegExp("(^|\\s)" + c + "(\\s|$)", 'g');
150 | 		e.className = e.className.replace(re, ' ');
151 | 	};
152 | 
153 | 	me.offset = function (el) {
154 | 		var left = -el.offsetLeft,
155 | 			top = -el.offsetTop;
156 | 
157 | 		// jshint -W084
158 | 		while (el = el.offsetParent) {
159 | 			left -= el.offsetLeft;
160 | 			top -= el.offsetTop;
161 | 		}
162 | 		// jshint +W084
163 | 
164 | 		return {
165 | 			left: left,
166 | 			top: top
167 | 		};
168 | 	};
169 | 
170 | 	me.preventDefaultException = function (el, exceptions) {
171 | 		for ( var i in exceptions ) {
172 | 			if ( exceptions[i].test(el[i]) ) {
173 | 				return true;
174 | 			}
175 | 		}
176 | 
177 | 		return false;
178 | 	};
179 | 
180 | 	me.extend(me.eventType = {}, {
181 | 		touchstart: 1,
182 | 		touchmove: 1,
183 | 		touchend: 1,
184 | 
185 | 		mousedown: 2,
186 | 		mousemove: 2,
187 | 		mouseup: 2,
188 | 
189 | 		pointerdown: 3,
190 | 		pointermove: 3,
191 | 		pointerup: 3,
192 | 
193 | 		MSPointerDown: 3,
194 | 		MSPointerMove: 3,
195 | 		MSPointerUp: 3
196 | 	});
197 | 
198 | 	me.extend(me.ease = {}, {
199 | 		quadratic: {
200 | 			style: 'cubic-bezier(0.25, 0.46, 0.45, 0.94)',
201 | 			fn: function (k) {
202 | 				return k * ( 2 - k );
203 | 			}
204 | 		},
205 | 		circular: {
206 | 			style: 'cubic-bezier(0.1, 0.57, 0.1, 1)',	// Not properly "circular" but this looks better, it should be (0.075, 0.82, 0.165, 1)
207 | 			fn: function (k) {
208 | 				return Math.sqrt( 1 - ( --k * k ) );
209 | 			}
210 | 		},
211 | 		back: {
212 | 			style: 'cubic-bezier(0.175, 0.885, 0.32, 1.275)',
213 | 			fn: function (k) {
214 | 				var b = 4;
215 | 				return ( k = k - 1 ) * k * ( ( b + 1 ) * k + b ) + 1;
216 | 			}
217 | 		},
218 | 		bounce: {
219 | 			style: '',
220 | 			fn: function (k) {
221 | 				if ( ( k /= 1 ) < ( 1 / 2.75 ) ) {
222 | 					return 7.5625 * k * k;
223 | 				} else if ( k < ( 2 / 2.75 ) ) {
224 | 					return 7.5625 * ( k -= ( 1.5 / 2.75 ) ) * k + 0.75;
225 | 				} else if ( k < ( 2.5 / 2.75 ) ) {
226 | 					return 7.5625 * ( k -= ( 2.25 / 2.75 ) ) * k + 0.9375;
227 | 				} else {
228 | 					return 7.5625 * ( k -= ( 2.625 / 2.75 ) ) * k + 0.984375;
229 | 				}
230 | 			}
231 | 		},
232 | 		elastic: {
233 | 			style: '',
234 | 			fn: function (k) {
235 | 				var f = 0.22,
236 | 					e = 0.4;
237 | 
238 | 				if ( k === 0 ) { return 0; }
239 | 				if ( k == 1 ) { return 1; }
240 | 
241 | 				return ( e * Math.pow( 2, - 10 * k ) * Math.sin( ( k - f / 4 ) * ( 2 * Math.PI ) / f ) + 1 );
242 | 			}
243 | 		}
244 | 	});
245 | 
246 | 	me.tap = function (e, eventName) {
247 | 		var ev = document.createEvent('Event');
248 | 		ev.initEvent(eventName, true, true);
249 | 		ev.pageX = e.pageX;
250 | 		ev.pageY = e.pageY;
251 | 		e.target.dispatchEvent(ev);
252 | 	};
253 | 
254 | 	me.click = function (e) {
255 | 		var target = e.target,
256 | 			ev;
257 | 
258 | 		if ( !(/(SELECT|INPUT|TEXTAREA)/i).test(target.tagName) ) {
259 | 			// https://developer.mozilla.org/en-US/docs/Web/API/MouseEvent/initMouseEvent
260 | 			// initMouseEvent is deprecated.
261 | 			ev = document.createEvent(window.MouseEvent ? 'MouseEvents' : 'Event');
262 | 			ev.initEvent('click', true, true);
263 | 			ev.view = e.view || window;
264 | 			ev.detail = 1;
265 | 			ev.screenX = target.screenX || 0;
266 | 			ev.screenY = target.screenY || 0;
267 | 			ev.clientX = target.clientX || 0;
268 | 			ev.clientY = target.clientY || 0;
269 | 			ev.ctrlKey = !!e.ctrlKey;
270 | 			ev.altKey = !!e.altKey;
271 | 			ev.shiftKey = !!e.shiftKey;
272 | 			ev.metaKey = !!e.metaKey;
273 | 			ev.button = 0;
274 | 			ev.relatedTarget = null;
275 | 			ev._constructed = true;
276 | 			target.dispatchEvent(ev);
277 | 		}
278 | 	};
279 | 
280 | 	me.getTouchAction = function(eventPassthrough, addPinch) {
281 | 		var touchAction = 'none';
282 | 		if ( eventPassthrough === 'vertical' ) {
283 | 			touchAction = 'pan-y';
284 | 		} else if (eventPassthrough === 'horizontal' ) {
285 | 			touchAction = 'pan-x';
286 | 		}
287 | 		if (addPinch && touchAction != 'none') {
288 | 			// add pinch-zoom support if the browser supports it, but if not (eg. Chrome <55) do nothing
289 | 			touchAction += ' pinch-zoom';
290 | 		}
291 | 		return touchAction;
292 | 	};
293 | 
294 | 	me.getRect = function(el) {
295 | 		if (el instanceof SVGElement) {
296 | 			var rect = el.getBoundingClientRect();
297 | 			return {
298 | 				top : rect.top,
299 | 				left : rect.left,
300 | 				width : rect.width,
301 | 				height : rect.height
302 | 			};
303 | 		} else {
304 | 			return {
305 | 				top : el.offsetTop,
306 | 				left : el.offsetLeft,
307 | 				width : el.offsetWidth,
308 | 				height : el.offsetHeight
309 | 			};
310 | 		}
311 | 	};
312 | 
313 | 	return me;
314 | })();


--------------------------------------------------------------------------------
/src/wheel/build.json:
--------------------------------------------------------------------------------
1 | {
2 | 	"insert": {
3 | 		"OPTIONS": "\t\tmouseWheelSpeed: 20,",
4 | 		"NORMALIZATION": "\tthis.options.invertWheelDirection = this.options.invertWheelDirection ? -1 : 1;",
5 | 		"_init": "\t\tif ( this.options.mouseWheel ) {\n\t\t\tthis._initWheel();\n\t\t}"
6 | 	}
7 | }


--------------------------------------------------------------------------------
/src/wheel/wheel.js:
--------------------------------------------------------------------------------
  1 | 
  2 | 	_initWheel: function () {
  3 | 		utils.addEvent(this.wrapper, 'wheel', this);
  4 | 		utils.addEvent(this.wrapper, 'mousewheel', this);
  5 | 		utils.addEvent(this.wrapper, 'DOMMouseScroll', this);
  6 | 
  7 | 		this.on('destroy', function () {
  8 | 			clearTimeout(this.wheelTimeout);
  9 | 			this.wheelTimeout = null;
 10 | 			utils.removeEvent(this.wrapper, 'wheel', this);
 11 | 			utils.removeEvent(this.wrapper, 'mousewheel', this);
 12 | 			utils.removeEvent(this.wrapper, 'DOMMouseScroll', this);
 13 | 		});
 14 | 	},
 15 | 
 16 | 	_wheel: function (e) {
 17 | 		if ( !this.enabled ) {
 18 | 			return;
 19 | 		}
 20 | 
 21 | 		e.preventDefault();
 22 | 
 23 | 		var wheelDeltaX, wheelDeltaY,
 24 | 			newX, newY,
 25 | 			that = this;
 26 | 
 27 | 		if ( this.wheelTimeout === undefined ) {
 28 | 			that._execEvent('scrollStart');
 29 | 		}
 30 | 
 31 | 		// Execute the scrollEnd event after 400ms the wheel stopped scrolling
 32 | 		clearTimeout(this.wheelTimeout);
 33 | 		this.wheelTimeout = setTimeout(function () {
 34 | 			if(!that.options.snap) {
 35 | 				that._execEvent('scrollEnd');
 36 | 			}
 37 | 			that.wheelTimeout = undefined;
 38 | 		}, 400);
 39 | 
 40 | 		if ( 'deltaX' in e ) {
 41 | 			if (e.deltaMode === 1) {
 42 | 				wheelDeltaX = -e.deltaX * this.options.mouseWheelSpeed;
 43 | 				wheelDeltaY = -e.deltaY * this.options.mouseWheelSpeed;
 44 | 			} else {
 45 | 				wheelDeltaX = -e.deltaX;
 46 | 				wheelDeltaY = -e.deltaY;
 47 | 			}
 48 | 		} else if ( 'wheelDeltaX' in e ) {
 49 | 			wheelDeltaX = e.wheelDeltaX / 120 * this.options.mouseWheelSpeed;
 50 | 			wheelDeltaY = e.wheelDeltaY / 120 * this.options.mouseWheelSpeed;
 51 | 		} else if ( 'wheelDelta' in e ) {
 52 | 			wheelDeltaX = wheelDeltaY = e.wheelDelta / 120 * this.options.mouseWheelSpeed;
 53 | 		} else if ( 'detail' in e ) {
 54 | 			wheelDeltaX = wheelDeltaY = -e.detail / 3 * this.options.mouseWheelSpeed;
 55 | 		} else {
 56 | 			return;
 57 | 		}
 58 | 
 59 | 		wheelDeltaX *= this.options.invertWheelDirection;
 60 | 		wheelDeltaY *= this.options.invertWheelDirection;
 61 | 
 62 | 		if ( !this.hasVerticalScroll ) {
 63 | 			wheelDeltaX = wheelDeltaY;
 64 | 			wheelDeltaY = 0;
 65 | 		}
 66 | 
 67 | 		if ( this.options.snap ) {
 68 | 			newX = this.currentPage.pageX;
 69 | 			newY = this.currentPage.pageY;
 70 | 
 71 | 			if ( wheelDeltaX > 0 ) {
 72 | 				newX--;
 73 | 			} else if ( wheelDeltaX < 0 ) {
 74 | 				newX++;
 75 | 			}
 76 | 
 77 | 			if ( wheelDeltaY > 0 ) {
 78 | 				newY--;
 79 | 			} else if ( wheelDeltaY < 0 ) {
 80 | 				newY++;
 81 | 			}
 82 | 
 83 | 			this.goToPage(newX, newY);
 84 | 
 85 | 			return;
 86 | 		}
 87 | 
 88 | 		newX = this.x + Math.round(this.hasHorizontalScroll ? wheelDeltaX : 0);
 89 | 		newY = this.y + Math.round(this.hasVerticalScroll ? wheelDeltaY : 0);
 90 | 
 91 | 		this.directionX = wheelDeltaX > 0 ? -1 : wheelDeltaX < 0 ? 1 : 0;
 92 | 		this.directionY = wheelDeltaY > 0 ? -1 : wheelDeltaY < 0 ? 1 : 0;
 93 | 
 94 | 		if ( newX > 0 ) {
 95 | 			newX = 0;
 96 | 		} else if ( newX < this.maxScrollX ) {
 97 | 			newX = this.maxScrollX;
 98 | 		}
 99 | 
100 | 		if ( newY > 0 ) {
101 | 			newY = 0;
102 | 		} else if ( newY < this.maxScrollY ) {
103 | 			newY = this.maxScrollY;
104 | 		}
105 | 
106 | 		this.scrollTo(newX, newY, 0);
107 | 
108 | // INSERT POINT: _wheel
109 | 	},
110 | 


--------------------------------------------------------------------------------
/src/zoom/build.json:
--------------------------------------------------------------------------------
 1 | {
 2 | 	"insert": {
 3 | 		"OPTIONS": "\t\tzoomMin: 1,\n\t\tzoomMax: 4, startZoom: 1,",
 4 | 		"DEFAULTS": "\tthis.scale = Math.min(Math.max(this.options.startZoom, this.options.zoomMin), this.options.zoomMax);",
 5 | 		"_init": "\t\tif ( this.options.zoom ) {\n\t\t\tthis._initZoom();\n\t\t}"
 6 | 	},
 7 | 	"replace": {
 8 | 		"refresh": "zoom/refresh.js",
 9 | 		"_translate": "\t\t\tthis.scrollerStyle[utils.style.transform] = 'translate(' + x + 'px,' + y + 'px) scale(' + this.scale + ') ' + this.translateZ;"
10 | 	}
11 | }


--------------------------------------------------------------------------------
/src/zoom/handleEvent.js:
--------------------------------------------------------------------------------
 1 | 
 2 | 	handleEvent: function (e) {
 3 | 		switch ( e.type ) {
 4 | 			case 'touchstart':
 5 | 			case 'pointerdown':
 6 | 			case 'MSPointerDown':
 7 | 			case 'mousedown':
 8 | 				this._start(e);
 9 | 
10 | 				if ( this.options.zoom && e.touches && e.touches.length > 1 ) {
11 | 					this._zoomStart(e);
12 | 				}
13 | 				break;
14 | 			case 'touchmove':
15 | 			case 'pointermove':
16 | 			case 'MSPointerMove':
17 | 			case 'mousemove':
18 | 				if ( this.options.zoom && e.touches && e.touches[1] ) {
19 | 					this._zoom(e);
20 | 					return;
21 | 				}
22 | 				this._move(e);
23 | 				break;
24 | 			case 'touchend':
25 | 			case 'pointerup':
26 | 			case 'MSPointerUp':
27 | 			case 'mouseup':
28 | 			case 'touchcancel':
29 | 			case 'pointercancel':
30 | 			case 'MSPointerCancel':
31 | 			case 'mousecancel':
32 | 				if ( this.scaled ) {
33 | 					this._zoomEnd(e);
34 | 					return;
35 | 				}
36 | 				this._end(e);
37 | 				break;
38 | 			case 'orientationchange':
39 | 			case 'resize':
40 | 				this._resize();
41 | 				break;
42 | 			case 'transitionend':
43 | 			case 'webkitTransitionEnd':
44 | 			case 'oTransitionEnd':
45 | 			case 'MSTransitionEnd':
46 | 				this._transitionEnd(e);
47 | 				break;
48 | 			case 'wheel':
49 | 			case 'DOMMouseScroll':
50 | 			case 'mousewheel':
51 | 				if ( this.options.wheelAction == 'zoom' ) {
52 | 					this._wheelZoom(e);
53 | 					return;	
54 | 				}
55 | 				this._wheel(e);
56 | 				break;
57 | 			case 'keydown':
58 | 				this._key(e);
59 | 				break;
60 | 		}
61 | 	}
62 | 
63 | };


--------------------------------------------------------------------------------
/src/zoom/refresh.js:
--------------------------------------------------------------------------------
1 | 
2 | 	this.scrollerWidth	= Math.round(rect.width * this.scale);
3 | 	this.scrollerHeight	= Math.round(rect.height * this.scale);
4 | 
5 | 	this.maxScrollX		= this.wrapperWidth - this.scrollerWidth;
6 | 	this.maxScrollY		= this.wrapperHeight - this.scrollerHeight;
7 | 


--------------------------------------------------------------------------------
/src/zoom/zoom.js:
--------------------------------------------------------------------------------
  1 | 
  2 | 	_initZoom: function () {
  3 | 		this.scrollerStyle[utils.style.transformOrigin] = '0 0';
  4 | 	},
  5 | 
  6 | 	_zoomStart: function (e) {
  7 | 		var c1 = Math.abs( e.touches[0].pageX - e.touches[1].pageX ),
  8 | 			c2 = Math.abs( e.touches[0].pageY - e.touches[1].pageY );
  9 | 
 10 | 		this.touchesDistanceStart = Math.sqrt(c1 * c1 + c2 * c2);
 11 | 		this.startScale = this.scale;
 12 | 
 13 | 		this.originX = Math.abs(e.touches[0].pageX + e.touches[1].pageX) / 2 + this.wrapperOffset.left - this.x;
 14 | 		this.originY = Math.abs(e.touches[0].pageY + e.touches[1].pageY) / 2 + this.wrapperOffset.top - this.y;
 15 | 
 16 | 		this._execEvent('zoomStart');
 17 | 	},
 18 | 
 19 | 	_zoom: function (e) {
 20 | 		if ( !this.enabled || utils.eventType[e.type] !== this.initiated ) {
 21 | 			return;
 22 | 		}
 23 | 
 24 | 		if ( this.options.preventDefault ) {
 25 | 			e.preventDefault();
 26 | 		}
 27 | 
 28 | 		var c1 = Math.abs( e.touches[0].pageX - e.touches[1].pageX ),
 29 | 			c2 = Math.abs( e.touches[0].pageY - e.touches[1].pageY ),
 30 | 			distance = Math.sqrt( c1 * c1 + c2 * c2 ),
 31 | 			scale = 1 / this.touchesDistanceStart * distance * this.startScale,
 32 | 			lastScale,
 33 | 			x, y;
 34 | 
 35 | 		this.scaled = true;
 36 | 
 37 | 		if ( scale < this.options.zoomMin ) {
 38 | 			scale = 0.5 * this.options.zoomMin * Math.pow(2.0, scale / this.options.zoomMin);
 39 | 		} else if ( scale > this.options.zoomMax ) {
 40 | 			scale = 2.0 * this.options.zoomMax * Math.pow(0.5, this.options.zoomMax / scale);
 41 | 		}
 42 | 
 43 | 		lastScale = scale / this.startScale;
 44 | 		x = this.originX - this.originX * lastScale + this.startX;
 45 | 		y = this.originY - this.originY * lastScale + this.startY;
 46 | 
 47 | 		this.scale = scale;
 48 | 
 49 | 		this.scrollTo(x, y, 0);
 50 | 	},
 51 | 
 52 | 	_zoomEnd: function (e) {
 53 | 		if ( !this.enabled || utils.eventType[e.type] !== this.initiated ) {
 54 | 			return;
 55 | 		}
 56 | 
 57 | 		if ( this.options.preventDefault ) {
 58 | 			e.preventDefault();
 59 | 		}
 60 | 
 61 | 		var newX, newY,
 62 | 			lastScale;
 63 | 
 64 | 		this.isInTransition = 0;
 65 | 		this.initiated = 0;
 66 | 
 67 | 		if ( this.scale > this.options.zoomMax ) {
 68 | 			this.scale = this.options.zoomMax;
 69 | 		} else if ( this.scale < this.options.zoomMin ) {
 70 | 			this.scale = this.options.zoomMin;
 71 | 		}
 72 | 
 73 | 		// Update boundaries
 74 | 		this.refresh();
 75 | 
 76 | 		lastScale = this.scale / this.startScale;
 77 | 
 78 | 		newX = this.originX - this.originX * lastScale + this.startX;
 79 | 		newY = this.originY - this.originY * lastScale + this.startY;
 80 | 
 81 | 		if ( newX > 0 ) {
 82 | 			newX = 0;
 83 | 		} else if ( newX < this.maxScrollX ) {
 84 | 			newX = this.maxScrollX;
 85 | 		}
 86 | 
 87 | 		if ( newY > 0 ) {
 88 | 			newY = 0;
 89 | 		} else if ( newY < this.maxScrollY ) {
 90 | 			newY = this.maxScrollY;
 91 | 		}
 92 | 
 93 | 		if ( this.x != newX || this.y != newY ) {
 94 | 			this.scrollTo(newX, newY, this.options.bounceTime);
 95 | 		}
 96 | 
 97 | 		this.scaled = false;
 98 | 
 99 | 		this._execEvent('zoomEnd');
100 | 	},
101 | 
102 | 	zoom: function (scale, x, y, time) {
103 | 		if ( scale < this.options.zoomMin ) {
104 | 			scale = this.options.zoomMin;
105 | 		} else if ( scale > this.options.zoomMax ) {
106 | 			scale = this.options.zoomMax;
107 | 		}
108 | 
109 | 		if ( scale == this.scale ) {
110 | 			return;
111 | 		}
112 | 
113 | 		var relScale = scale / this.scale;
114 | 
115 | 		x = x === undefined ? this.wrapperWidth / 2 : x;
116 | 		y = y === undefined ? this.wrapperHeight / 2 : y;
117 | 		time = time === undefined ? 300 : time;
118 | 
119 | 		x = x + this.wrapperOffset.left - this.x;
120 | 		y = y + this.wrapperOffset.top - this.y;
121 | 
122 | 		x = x - x * relScale + this.x;
123 | 		y = y - y * relScale + this.y;
124 | 
125 | 		this.scale = scale;
126 | 
127 | 		this.refresh();		// update boundaries
128 | 
129 | 		if ( x > 0 ) {
130 | 			x = 0;
131 | 		} else if ( x < this.maxScrollX ) {
132 | 			x = this.maxScrollX;
133 | 		}
134 | 
135 | 		if ( y > 0 ) {
136 | 			y = 0;
137 | 		} else if ( y < this.maxScrollY ) {
138 | 			y = this.maxScrollY;
139 | 		}
140 | 
141 | 		this.scrollTo(x, y, time);
142 | 	},
143 | 
144 | 	_wheelZoom: function (e) {
145 | 		var wheelDeltaY,
146 | 			deltaScale,
147 | 			that = this;
148 | 
149 | 		// Execute the zoomEnd event after 400ms the wheel stopped scrolling
150 | 		clearTimeout(this.wheelTimeout);
151 | 		this.wheelTimeout = setTimeout(function () {
152 | 			that._execEvent('zoomEnd');
153 | 		}, 400);
154 | 
155 | 		if ( 'deltaX' in e ) {
156 | 			wheelDeltaY = -e.deltaY / Math.abs(e.deltaY);
157 | 		} else if ('wheelDeltaX' in e) {
158 | 			wheelDeltaY = e.wheelDeltaY / Math.abs(e.wheelDeltaY);
159 | 		} else if('wheelDelta' in e) {
160 | 			wheelDeltaY = e.wheelDelta / Math.abs(e.wheelDelta);
161 | 		} else if ('detail' in e) {
162 | 			wheelDeltaY = -e.detail / Math.abs(e.wheelDelta);
163 | 		} else {
164 | 			return;
165 | 		}
166 | 
167 | 		deltaScale = this.scale + wheelDeltaY / 5;
168 | 
169 | 		this.zoom(deltaScale, e.pageX, e.pageY, 0);
170 | 	},
171 | 


--------------------------------------------------------------------------------