fullPage.js 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841
  1. function FullPage(options) {
  2. "use strict";
  3. var pageContain = document.getElementById(options.id),
  4. page = pageContain.children,
  5. pagelen = page.length,
  6. iPage = pagelen,
  7. sTime = options.slideTime || 800,
  8. effect = options.effect || {},
  9. indexNow = 0,
  10. browser = {},
  11. pageRange = {},
  12. cubicCurve = {},
  13. pageStyle = [],
  14. mode = [],
  15. modeLen,
  16. navChildren,
  17. SPACE = ' ',
  18. _interval = null,
  19. _isLocked = false,
  20. _isNav = false,
  21. _curve,
  22. _t,
  23. _fix,
  24. init,
  25. setCubic,
  26. trans,
  27. resetAndRun,
  28. onTap,
  29. replaceClass,
  30. goPage,
  31. navChange,
  32. wheelScroll;
  33. if (!page || pagelen === 1) return;
  34. if (options.mode) {
  35. _isNav = options.mode.indexOf('nav:') !== -1;
  36. mode = options.mode.split(',');
  37. modeLen = mode.length;
  38. }
  39. for (_t = 0; _t < pagelen; _t++) {
  40. pageStyle.push(page[_t].style);
  41. }
  42. browser = {
  43. addEventListener : !!window.addEventListener,
  44. gravity : !!window.DeviceOrientationEvent,
  45. touch : ('ontouchstart' in window) ||
  46. window.DocumentTouch && document instanceof DocumentTouch,
  47. version: function() {
  48. var u = navigator.userAgent,
  49. matchVersion = u.indexOf('Android'),
  50. num;
  51. _fix = u.indexOf('QQBrowser') !== -1 ? 200 : 0;
  52. if (matchVersion !== -1) {
  53. num = u.substring(matchVersion + 7, matchVersion + 11).replace(' ', '');
  54. }
  55. return num || 0; //0: not Android device
  56. }(),
  57. cssCore: function(testCss) {
  58. switch (true) {
  59. case testCss.webkitTransition === '':
  60. return 'webkit'; break;
  61. case testCss.MozTransition === '':
  62. return 'Moz'; break;
  63. case testCss.msTransition === '':
  64. return 'ms'; break;
  65. case testCss.OTransition === '':
  66. return 'O'; break;
  67. default:
  68. return '';
  69. }
  70. }(document.createElement('Chriswang').style)
  71. };
  72. function UnitBezier(p1x, p1y, p2x, p2y) {
  73. // pre-calculate the polynomial coefficients
  74. // First and last control points are implied to be (0,0) and (1.0, 1.0)
  75. this.cx = 3.0 * p1x;
  76. this.bx = 3.0 * (p2x - p1x) - this.cx;
  77. this.ax = 1.0 - this.cx -this.bx;
  78. this.cy = 3.0 * p1y;
  79. this.by = 3.0 * (p2y - p1y) - this.cy;
  80. this.ay = 1.0 - this.cy - this.by;
  81. }
  82. UnitBezier.prototype = {
  83. epsilon : 1e-5, // Precision
  84. sampleCurveX : function(t) {
  85. return ((this.ax * t + this.bx) * t + this.cx) * t;
  86. },
  87. sampleCurveY : function(t) {
  88. return ((this.ay * t + this.by) * t + this.cy) * t;
  89. },
  90. sampleCurveDerivativeX : function(t) {
  91. return (3.0 * this.ax * t + 2.0 * this.bx) * t + this.cx;
  92. },
  93. solveCurveX : function(x, epsilon) {
  94. var t0,
  95. t1,
  96. t2,
  97. x2,
  98. d2,
  99. i;
  100. // First try a few iterations of Newton's method -- normally very fast.
  101. for (t2 = x, i = 0; i < 8; i++) {
  102. x2 = this.sampleCurveX(t2) - x;
  103. if (Math.abs (x2) < epsilon)
  104. return t2;
  105. d2 = this.sampleCurveDerivativeX(t2);
  106. if (Math.abs(d2) < epsilon)
  107. break;
  108. t2 = t2 - x2 / d2;
  109. }
  110. // No solution found - use bi-section
  111. t0 = 0.0;
  112. t1 = 1.0;
  113. t2 = x;
  114. if (t2 < t0) return t0;
  115. if (t2 > t1) return t1;
  116. while (t0 < t1) {
  117. x2 = this.sampleCurveX(t2);
  118. if (Math.abs(x2 - x) < epsilon)
  119. return t2;
  120. if (x > x2) t0 = t2;
  121. else t1 = t2;
  122. t2 = (t1 - t0) * .5 + t0;
  123. }
  124. // Give up
  125. return t2;
  126. },
  127. // Find new T as a function of Y along curve X
  128. solve : function(x, epsilon) {
  129. return this.sampleCurveY( this.solveCurveX(x, epsilon) );
  130. }
  131. }
  132. init = function() {
  133. var i = pagelen;
  134. pageRange = {
  135. X : document.documentElement.clientWidth || window.innerWidth,
  136. Y : document.documentElement.clientHeight || window.innerHeight
  137. }
  138. pageContain.style.height = pageRange.Y + 'px';
  139. }
  140. setCubic = function(a, b, c, d) {
  141. cubicCurve.A = a;
  142. cubicCurve.B = b;
  143. cubicCurve.C = c;
  144. cubicCurve.D = d;
  145. }
  146. if (typeof options.easing === 'string') {
  147. switch (options.easing) {
  148. case 'ease' :
  149. setCubic(0.25, 0.1, 0.25, 1);
  150. break;
  151. case 'linear' :
  152. setCubic(0, 0, 1, 1);
  153. break;
  154. case 'ease-in' :
  155. setCubic(0.42, 0, 1, 1);
  156. break;
  157. case 'ease-out' :
  158. setCubic(0, 0, 0.58, 1);
  159. break;
  160. case 'ease-in-out' :
  161. setCubic(0.42, 0, 0.58, 1);
  162. break;
  163. }
  164. } else {
  165. setCubic(options.easing[0], options.easing[1], options.easing[2], options.easing[3]);
  166. }
  167. if (browser.cssCore !== '') {
  168. while (iPage--) {
  169. pageStyle[iPage][browser.cssCore + 'TransitionTimingFunction'] = 'cubic-bezier('
  170. + cubicCurve.A + ','
  171. + cubicCurve.B + ','
  172. + cubicCurve.C + ','
  173. + cubicCurve.D + ')';
  174. }
  175. trans = function(o, x, y, t) {
  176. var s = o.style,
  177. c = 'translate(' + x +'px,' + y + 'px) translateZ(0)',
  178. a = arguments[4];
  179. if (a.scale) {
  180. c += t === 0 ? ' scale(' + a.scale[0] + ')'
  181. : ' scale(' + a.scale[1] + ')';
  182. }
  183. if (a.rotate) {
  184. c += t === 0 ? ' rotate(' + a.rotate[0] + 'deg)'
  185. : ' rotate(' + a.rotate[1] + 'deg)';
  186. }
  187. s[browser.cssCore + 'TransformOrigin'] = '50% 50%';
  188. s[browser.cssCore + 'Transform'] = c;
  189. }
  190. } else {
  191. // simulate translate for ie9-
  192. // Cubic-bezier : Fn(t) = (3p1-3p2+1)t^3+(3p2-6p1)t^2-3p1t.
  193. _curve = new UnitBezier(cubicCurve.A, cubicCurve.B, cubicCurve.C, cubicCurve.D);
  194. trans = function(o, x, y, t) {
  195. var cs = o.currentStyle,
  196. s = o.style,
  197. cx = parseInt(s.left || cs.left, 10),
  198. cy = parseInt(s.top || cs.top, 10),
  199. dx = x - cx,
  200. dy = y - cy,
  201. ft = +new Date,
  202. end = ft + t,
  203. pos = 0,
  204. e = effect.opacity,
  205. diff;
  206. clearInterval(_interval);
  207. _interval = setInterval(function() {
  208. var _t;
  209. if (+new Date > end) {
  210. _t = e ? 'left:' + x + 'px;top:' + y + 'px;filter:alpha(opacity=' + 100 * e[1] + ');'
  211. : 'left:' + x + 'px;top:' + y + 'px;';
  212. clearInterval(_interval);
  213. } else {
  214. diff = end - new Date;
  215. pos = diff / t;
  216. // fix to cubic-bezier
  217. pos = _curve.solve(1 - pos, UnitBezier.prototype.epsilon);
  218. _t = 'left:' + (cx + dx * pos)
  219. + 'px;top:' + (cy + dy * pos)
  220. + 'px;'
  221. if (e) {
  222. _t += 'filter:alpha(opacity=' + 100 * ( e[1] * pos - e[0] * (1 - pos) )+ ');'
  223. }
  224. }
  225. s.cssText = _t;
  226. }, 13);
  227. }
  228. }
  229. resetAndRun = {
  230. transform : function(o, from, to) {
  231. var rangeNow = 0,
  232. fix = browser.cssCore === ''
  233. && (o['translate'] === 'none' || !o.translate ) ? -50 : _fix;
  234. switch (o['translate']) {
  235. case 'Y' :
  236. rangeNow = to > from ? pageRange.Y : - pageRange.Y;
  237. trans(page[to], 0, rangeNow, 0, o);
  238. break;
  239. case 'X' :
  240. rangeNow = to > from ? pageRange.X : - pageRange.X;
  241. trans(page[to], rangeNow, 0, 0, o);
  242. break;
  243. case 'XY' :
  244. rangeNow = {
  245. X : to > from ? pageRange.X : - pageRange.X,
  246. Y : to > from ? pageRange.Y : - pageRange.Y
  247. }
  248. trans(page[to], rangeNow.X, rangeNow.Y, 0, o);
  249. break;
  250. default:
  251. trans(page[to], 0, 0, 0, o);
  252. break;
  253. }
  254. setTimeout(function() {
  255. trans(page[to], 0, 0, sTime, o);
  256. }, fix + 50);
  257. },
  258. opacity : function(o, from, to) {
  259. var s = page[to].style;
  260. s.opacity = o[0];
  261. setTimeout(function() {
  262. s.opacity = o[1];
  263. }, 70);
  264. }
  265. }
  266. if (browser.addEventListener && browser.touch) {
  267. if (navigator.userAgent.indexOf('Firefox')) {
  268. onTap = function(o, fn) {
  269. o.addEventListener('click', fn, false);
  270. }
  271. } else {
  272. onTap = function (o, fn) {
  273. o.addEventListener('touchstart', fn, false);
  274. if (arguments[2]) {
  275. // if we touch on navBar we should stop scroll
  276. o.addEventListener('touchmove', function(e) {
  277. e.preventDefault();
  278. }, false);
  279. }
  280. }
  281. }
  282. } else {
  283. onTap = function (o, fn) {
  284. o.onclick = fn;
  285. }
  286. }
  287. replaceClass = function(o, cls, tocls) {
  288. var oN = o.className,
  289. arr = [],
  290. len;
  291. if (oN.indexOf(cls) !== -1) {
  292. arr = oN.split(SPACE);
  293. len = arr.length;
  294. while (len--) {
  295. if (arr[len] === cls) {
  296. if (tocls === SPACE || tocls === '') {
  297. arr.splice(len, 1);
  298. } else {
  299. arr[len] = tocls;
  300. }
  301. }
  302. }
  303. if (arr.length) {
  304. o.className = arr.join(SPACE);
  305. } else {
  306. o.removeAttribute('class');
  307. o.removeAttribute('className');
  308. }
  309. }
  310. }
  311. if (_isNav) {
  312. navChange = function(from, to) {
  313. var t = navChildren[to].className;
  314. replaceClass(navChildren[from], 'active', SPACE);
  315. navChildren[to].className = t === '' ? 'active' : t + ' active';
  316. }
  317. }
  318. goPage = function(to) {
  319. var fix = _fix,
  320. indexOld,
  321. _effectNow;
  322. if (_isLocked // make sure translate is already
  323. || to === indexNow // don't translate if thispage
  324. || to >= pagelen // more than max page
  325. || to < 0) return; // less than min page(0)
  326. _isLocked = true;
  327. for (_effectNow in effect) {
  328. resetAndRun[_effectNow](effect[_effectNow], indexNow, to);
  329. }
  330. fix += browser.cssCore === '' ? 20 : 0 ;
  331. indexOld = indexNow;
  332. indexNow = to;
  333. if (_isNav) navChange(indexOld, indexNow);
  334. setTimeout(function() {
  335. // fix for bug in ie6-9 about z-index
  336. page[to].className += ' slide';
  337. }, fix);
  338. setTimeout(function() {
  339. pageStyle[to][browser.cssCore + 'TransitionDuration'] = sTime + 'ms';
  340. }, 20);
  341. setTimeout(function() {
  342. replaceClass(page[indexOld], 'current', '');
  343. replaceClass(page[indexNow], 'slide', 'current');
  344. if (options.callback) {
  345. options.callback(indexNow, page[indexNow]);
  346. }
  347. _isLocked = false;
  348. }, sTime + _fix + 120);
  349. $('video').trigger('pause');
  350. $('audio').trigger('pause');
  351. }
  352. init();
  353. // Tag first page
  354. _t = page[indexNow].className;
  355. page[indexNow].className = _t.indexOf('current') !== -1 ? _t : _t + ' current';
  356. if (browser.addEventListener) {
  357. window.addEventListener('resize', init, false);
  358. } else {
  359. window.onresize = init;
  360. }
  361. // check mode
  362. while (modeLen--) {
  363. (function(m) {
  364. switch (true) {
  365. case m === 'wheel' :
  366. wheelScroll = function(e) {
  367. var direct;
  368. e = e || window.event;
  369. if (e.preventDefault) {
  370. e.preventDefault();
  371. } else {
  372. e.returnValue = false;
  373. }
  374. if(e.target&&e.target.className&&e.target&&e.target.className.includes('nrNull')){
  375. return
  376. }
  377. if (_isLocked) return;
  378. direct = - e.wheelDelta || e.detail;
  379. direct = direct < 0 ? -1 : 1;
  380. goPage(indexNow + direct);
  381. //alert("测试");
  382. }
  383. if (browser.addEventListener) {
  384. document.addEventListener('DOMMouseScroll', wheelScroll, false);
  385. }
  386. window.onmousewheel = document.onmousewheel = wheelScroll;
  387. break;
  388. case m === 'touch' :
  389. if (!browser.touch || !browser.addEventListener) break;
  390. (function() {
  391. var pageIndexMax = pagelen - 1,
  392. scaleStart = effect.transform.scale[0],
  393. scaleDiff = effect.transform.scale[1] - scaleStart,
  394. rotateStart = effect.transform.rotate[0],
  395. rotateDiff = effect.transform.rotate[1] - rotateStart,
  396. opacityStart = effect.opacity[0],
  397. opacityDiff = effect.opacity[1] - opacityStart,
  398. touchEvent = {},
  399. start = {},
  400. delta = {},
  401. isValidMove = false,
  402. prev,
  403. next,
  404. setIndex,
  405. reset,
  406. validReset,
  407. move,
  408. _interval,
  409. _t;
  410. if (effect.transform.translate === 'Y') {
  411. setIndex = function() {
  412. prev = pageStyle[indexNow - 1];
  413. next = pageStyle[indexNow + 1];
  414. if (prev) {
  415. prev[browser.cssCore + 'TransitionDuration'] = '0ms';
  416. prev[browser.cssCore + 'Transform'] = 'translate(0,-' + pageRange.Y + 'px) translateZ(0)';
  417. prev[browser.cssCore + 'TransformOrigin'] = '50% 100%';
  418. page[indexNow - 1].className += ' swipe';
  419. }
  420. if (next) {
  421. next[browser.cssCore + 'TransitionDuration'] = '0ms';
  422. next[browser.cssCore + 'Transform'] = 'translate(0,' + pageRange.Y + 'px) translateZ(0)';
  423. next[browser.cssCore + 'TransformOrigin'] = '50% 0%';
  424. page[indexNow + 1].className += ' swipe';
  425. }
  426. }
  427. move = function (o) {
  428. var pos = Math.abs(o.y / pageRange.Y),
  429. _t = ' scale(' + (scaleStart + scaleDiff * pos)
  430. + ') rotate(' + (rotateStart + rotateDiff * pos) + 'deg)';
  431. if (prev && o.y > 0) {
  432. prev.opacity = (opacityStart + opacityDiff * pos);
  433. prev[browser.cssCore + 'Transform'] = 'translate(0,' + (o.y - pageRange.Y) + 'px) translateZ(0)' + _t;
  434. }
  435. if (next && o.y < 0) {
  436. next.opacity = (opacityStart + opacityDiff * pos);
  437. next[browser.cssCore + 'Transform'] = 'translate(0,' + (pageRange.Y + o.y) + 'px) translateZ(0)' + _t;
  438. }
  439. }
  440. reset = function(s, n) {
  441. var _t = sTime >> 1;
  442. replaceClass(page[indexNow + n], 'swipe', 'slide');
  443. s.opacity = 1;
  444. s[browser.cssCore + 'TransitionDuration'] = _t + 'ms';
  445. s[browser.cssCore + 'Transform'] = 'translate(0,'+ n * pageRange.Y + 'px) translateZ(0)';
  446. setTimeout(function() {
  447. replaceClass(page[indexNow + n], 'slide', '');
  448. setTimeout(function() {
  449. _isLocked = false;
  450. }, 50);
  451. }, _t);
  452. }
  453. validReset = function(s, n) {
  454. var to = indexNow + n,
  455. _t = ~~(sTime / 1.5),
  456. _o = page[indexNow - n];
  457. if (_o) {
  458. replaceClass(_o, 'swipe', '');
  459. }
  460. if (to < 0 || to > pagelen - 1) {
  461. setTimeout(function() {
  462. _isLocked = false;
  463. }, 50);
  464. return;
  465. }
  466. if (_isNav) {
  467. navChange(indexNow, to);
  468. }
  469. s.opacity = 1;
  470. replaceClass(page[to], 'swipe', 'slide');
  471. s[browser.cssCore + 'TransitionDuration'] = _t + 'ms';
  472. s[browser.cssCore + 'Transform'] = 'translate(0,0) translateZ(0)';
  473. setTimeout(function() {
  474. replaceClass(page[indexNow], 'current', '');
  475. replaceClass(page[to], 'slide', 'current');
  476. indexNow = to;
  477. if (options.callback) {
  478. options.callback(indexNow, page[indexNow]);
  479. }
  480. setTimeout(function() {
  481. _isLocked = false;
  482. }, 50)
  483. }, _t);
  484. }
  485. } else {
  486. setIndex = function() {
  487. prev = pageStyle[indexNow - 1];
  488. next = pageStyle[indexNow + 1];
  489. if (prev) {
  490. prev[browser.cssCore + 'TransitionDuration'] = '0ms';
  491. prev[browser.cssCore + 'Transform'] = 'translate(-' + pageRange.X + 'px,0) translateZ(0)';
  492. prev[browser.cssCore + 'TransformOrigin'] = '100% 50%';
  493. page[indexNow - 1].className += ' swipe';
  494. }
  495. if (next) {
  496. next[browser.cssCore + 'TransitionDuration'] = '0ms';
  497. next[browser.cssCore + 'Transform'] = 'translate(' + pageRange.X + 'px,0) translateZ(0)';
  498. next[browser.cssCore + 'TransformOrigin'] = '0 50%';
  499. page[indexNow + 1].className += ' swipe';
  500. }
  501. }
  502. move = function (o) {
  503. var pos = Math.abs(o.x / pageRange.X),
  504. _t = ' scale(' + (scaleStart + scaleDiff * pos)
  505. + ') rotate(' + (rotateStart + rotateDiff * pos) + 'deg)';
  506. if (prev && o.x > 0) {
  507. console.log()
  508. prev.opacity = (opacityStart + opacityDiff * pos);
  509. prev[browser.cssCore + 'Transform'] = 'translate(' + (o.x - pageRange.X) + 'px,0) translateZ(0)' + _t;
  510. }
  511. if (next && o.x < 0) {
  512. next.opacity = (opacityStart + opacityDiff * pos);
  513. next[browser.cssCore + 'Transform'] = 'translate(' + (pageRange.X + o.x) + 'px,0) translateZ(0)' + _t;
  514. }
  515. }
  516. reset = function(s, n) {
  517. var _t = sTime >> 1;
  518. replaceClass(page[indexNow + n], 'swipe', 'slide');
  519. s.opacity = 1;
  520. s[browser.cssCore + 'TransitionDuration'] = _t + 'ms';
  521. s[browser.cssCore + 'Transform'] = 'translate('+ n * pageRange.X + 'px,0) translateZ(0)';
  522. setTimeout(function() {
  523. replaceClass(page[indexNow + n], 'slide', '');
  524. setTimeout(function() {
  525. _isLocked = false;
  526. }, 50);
  527. }, _t);
  528. }
  529. validReset = function(s, n) {
  530. var to = indexNow + n,
  531. _t = ~~(sTime / 1.5),
  532. _o = page[indexNow - n];
  533. if (_o) {
  534. replaceClass(_o, 'swipe', '');
  535. }
  536. if (to < 0 || to > pagelen - 1) {
  537. setTimeout(function() {
  538. _isLocked = false;
  539. }, 50);
  540. return;
  541. }
  542. if (_isNav) {
  543. navChange(indexNow, to);
  544. }
  545. replaceClass(page[to], 'swipe', 'slide');
  546. s.opacity = 1;
  547. s[browser.cssCore + 'TransitionDuration'] = _t + 'ms';
  548. s[browser.cssCore + 'Transform'] = 'translate(0,0) translateZ(0)';
  549. setTimeout(function() {
  550. replaceClass(page[indexNow], 'current', '');
  551. replaceClass(page[to], 'slide', 'current');
  552. indexNow = to;
  553. if (options.callback) {
  554. options.callback(indexNow, page[indexNow]);
  555. }
  556. setTimeout(function() {
  557. _isLocked = false;
  558. }, 50)
  559. }, _t);
  560. }
  561. }
  562. touchEvent = {
  563. start : function(e) {
  564. var touches = e.touches[0];
  565. if (_isLocked) return;
  566. _isLocked = true;
  567. start = {
  568. x : touches.pageX,
  569. y : touches.pageY,
  570. time : +new Date
  571. }
  572. // reset
  573. delta = {};
  574. isValidMove = false;
  575. setIndex();
  576. pageContain.addEventListener('touchmove', touchEvent.move, false);
  577. pageContain.addEventListener('touchend', touchEvent.end, false);
  578. },
  579. move : function(e) {
  580. var touches = e.touches[0];
  581. e.preventDefault();
  582. // ensure swiping with one touch and not pinching
  583. if ( event.touches.length > 1 || event.scale && event.scale !== 1) return
  584. delta = {
  585. x : touches.pageX - start.x,
  586. y : touches.pageY - start.y
  587. }
  588. if (!isValidMove) {
  589. _t = Math.abs(delta.x) > Math.abs(delta.y) ? 'X' : 'Y';
  590. _t = _t === options.effect.transform['translate'] ? true : false;
  591. isValidMove = true;
  592. } else {
  593. if (_t) move(delta);
  594. }
  595. },
  596. end : function(e) {
  597. var touches = e.changedTouches[0],
  598. duration = +new Date - start.time,
  599. abs = {},
  600. nextDiff = 0,
  601. isValidSlide = false;
  602. delta = {
  603. x : touches.pageX - start.x,
  604. y : touches.pageY - start.y
  605. }
  606. abs = {
  607. x : Math.abs(delta.x),
  608. y : Math.abs(delta.y)
  609. }
  610. switch (options.effect.transform['translate']) {
  611. case 'Y' :
  612. isValidSlide =
  613. + duration < 250 && abs.y > 30
  614. || abs.y > pageRange.Y * .3;
  615. nextDiff = delta.y > 0 ? -1 : 1;
  616. break;
  617. case 'X' :
  618. isValidSlide =
  619. + duration < 250 && abs.x > 30
  620. || abs.x > pageRange.X * .3;
  621. nextDiff = delta.x > 0 ? -1 : 1;
  622. break;
  623. default :
  624. isValidSlide =
  625. + duration < 350 && abs.y + abs.x > 50
  626. || abs.y > pageRange.Y * .3
  627. || abs.x > pageRange.X * .3;
  628. nextDiff = abs.x > abs.y ?
  629. delta.x > 0 ? -1 : 1
  630. : delta.y > 0 ? -1 : 1;
  631. break;
  632. }
  633. if (!isValidSlide || !_t) {
  634. if (prev) reset(prev, - 1);
  635. if (next) reset(next, + 1);
  636. } else {
  637. if (nextDiff === -1) {
  638. validReset(prev, -1);
  639. } else {
  640. validReset(next, 1);
  641. }
  642. }
  643. pageContain.removeEventListener('touchmove', touchEvent.move, false);
  644. pageContain.removeEventListener('touchend', touchEvent.end, false);
  645. }
  646. }
  647. pageContain.addEventListener('touchstart', touchEvent.start, false);
  648. }());
  649. break;
  650. case m.indexOf('nav:') !== -1 :
  651. (function() {
  652. var navId = m.split(':')[1],
  653. navObj = document.getElementById(navId),
  654. navLen,
  655. gotoPage,
  656. _t;
  657. navChildren = navObj.children;
  658. navLen = navChildren.length;
  659. _t = navChildren[indexNow].className;
  660. if (!navObj || !navChildren) return;
  661. while (navLen--) {
  662. // set attr for finding specific page
  663. navChildren[navLen].setAttribute('data-page', navLen);
  664. }
  665. if (_t.indexOf('active') === -1) {
  666. navChildren[indexNow].className = _t === '' ? 'active' : _t + ' active';
  667. }
  668. gotoPage = function(e) {
  669. var t;
  670. e = e || window.event;
  671. e = e.target || e.srcElement;
  672. t = e.tagName.toLowerCase();
  673. while (t !== 'li') {
  674. if (t === 'ul') return;
  675. e = e.parentNode;
  676. t = e.tagName.toLowerCase();
  677. }
  678. goPage( + e.getAttribute('data-page') );
  679. }
  680. // bind event to navObj
  681. onTap(navObj, gotoPage, 1);
  682. }());
  683. }
  684. }(mode[modeLen]));
  685. }
  686. return {
  687. thisPage : function() {
  688. return indexNow;
  689. },
  690. go : function(num) {
  691. goPage(num);
  692. },
  693. next : function() {
  694. goPage(indexNow + 1);
  695. },
  696. prev : function() {
  697. goPage(indexNow - 1);
  698. }
  699. }
  700. }