touchSlider.js 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489
  1. (function(E) {
  2. E.fn.drag = function(L, K, J) {
  3. if (K) {
  4. this.bind("dragstart", L)
  5. }
  6. if (J) {
  7. this.bind("dragend", J)
  8. }
  9. return !L ? this.trigger("drag") : this.bind("drag", K ? K : L)
  10. }
  11. ;
  12. var A = E.event
  13. , B = A.special
  14. , F = B.drag = {
  15. not: ":input",
  16. distance: 0,
  17. which: 1,
  18. dragging: false,
  19. setup: function(J) {
  20. J = E.extend({
  21. distance: F.distance,
  22. which: F.which,
  23. not: F.not
  24. }, J || {});
  25. J.distance = I(J.distance);
  26. A.add(this, "mousedown", H, J);
  27. if (this.attachEvent) {
  28. this.attachEvent("ondragstart", D)
  29. }
  30. },
  31. teardown: function() {
  32. A.remove(this, "mousedown", H);
  33. if (this === F.dragging) {
  34. F.dragging = F.proxy = false
  35. }
  36. G(this, true);
  37. if (this.detachEvent) {
  38. this.detachEvent("ondragstart", D)
  39. }
  40. }
  41. };
  42. B.dragstart = B.dragend = {
  43. setup: function() {},
  44. teardown: function() {}
  45. };
  46. function H(L) {
  47. var K = this, J, M = L.data || {};
  48. if (M.elem) {
  49. K = L.dragTarget = M.elem;
  50. L.dragProxy = F.proxy || K;
  51. L.cursorOffsetX = M.pageX - M.left;
  52. L.cursorOffsetY = M.pageY - M.top;
  53. L.offsetX = L.pageX - L.cursorOffsetX;
  54. L.offsetY = L.pageY - L.cursorOffsetY
  55. } else {
  56. if (F.dragging || (M.which > 0 && L.which != M.which) || E(L.target).is(M.not)) {
  57. return
  58. }
  59. }
  60. switch (L.type) {
  61. case "mousedown":
  62. E.extend(M, E(K).offset(), {
  63. elem: K,
  64. target: L.target,
  65. pageX: L.pageX,
  66. pageY: L.pageY
  67. });
  68. A.add(document, "mousemove mouseup", H, M);
  69. G(K, false);
  70. F.dragging = null;
  71. return false;
  72. case !F.dragging && "mousemove":
  73. if (I(L.pageX - M.pageX) + I(L.pageY - M.pageY) < M.distance) {
  74. break
  75. }
  76. L.target = M.target;
  77. J = C(L, "dragstart", K);
  78. if (J !== false) {
  79. F.dragging = K;
  80. F.proxy = L.dragProxy = E(J || K)[0]
  81. }
  82. case "mousemove":
  83. if (F.dragging) {
  84. J = C(L, "drag", K);
  85. if (B.drop) {
  86. B.drop.allowed = (J !== false);
  87. B.drop.handler(L)
  88. }
  89. if (J !== false) {
  90. break
  91. }
  92. L.type = "mouseup"
  93. }
  94. case "mouseup":
  95. A.remove(document, "mousemove mouseup", H);
  96. if (F.dragging) {
  97. if (B.drop) {
  98. B.drop.handler(L)
  99. }
  100. C(L, "dragend", K)
  101. }
  102. G(K, true);
  103. F.dragging = F.proxy = M.elem = false;
  104. break
  105. }
  106. return true
  107. }
  108. function C(M, K, L) {
  109. M.type = K;
  110. var J = E.event.handle.call(L, M);
  111. return J === false ? false : J || M.result
  112. }
  113. function I(J) {
  114. return Math.pow(J, 2)
  115. }
  116. function D() {
  117. return (F.dragging === false)
  118. }
  119. function G(K, J) {
  120. if (!K) {
  121. return
  122. }
  123. K.unselectable = J ? "off" : "on";
  124. K.onselectstart = function() {
  125. return J
  126. }
  127. ;
  128. if (K.style) {
  129. K.style.MozUserSelect = J ? "" : "none"
  130. }
  131. }
  132. }
  133. )(jQuery);
  134. (function($) {
  135. $.fn.touchSlider = function(settings) {
  136. settings.supportsCssTransitions = (function(style) {
  137. var prefixes = ['Webkit', 'Moz', 'Ms'];
  138. for (var i = 0, l = prefixes.length; i < l; i++) {
  139. if (typeof style[prefixes[i] + 'Transition'] !== 'undefined') {
  140. return true;
  141. }
  142. }
  143. return false;
  144. }
  145. )(document.createElement('div').style);
  146. settings = jQuery.extend({
  147. roll: true,
  148. flexible: false,
  149. btn_prev: null,
  150. btn_next: null,
  151. paging: null,
  152. speed: 75,
  153. view: 1,
  154. range: 0.15,
  155. page: 1,
  156. transition: false,
  157. initComplete: null,
  158. counter: null,
  159. multi: false
  160. }, settings);
  161. var opts = [];
  162. opts = $.extend({}, $.fn.touchSlider.defaults, settings);
  163. return this.each(function() {
  164. $.fn.extend(this, touchSlider);
  165. var _this = this;
  166. this.opts = opts;
  167. this._view = this.opts.view;
  168. this._speed = this.opts.speed;
  169. this._tg = $(this);
  170. this._list = this._tg.children().children();
  171. this._width = parseInt(this._tg.css("width"));
  172. this._item_w = parseInt(this._list.css("width"));
  173. this._len = this._list.length;
  174. this._range = this.opts.range * this._width;
  175. this._pos = [];
  176. this._start = [];
  177. this._startX = 0;
  178. this._startY = 0;
  179. this._left = 0;
  180. this._top = 0;
  181. this._drag = false;
  182. this._scroll = false;
  183. this._btn_prev;
  184. this._btn_next;
  185. this.init();
  186. $(this).bind("touchstart", this.touchstart).bind("touchmove", this.touchmove).bind("touchend", this.touchend).bind("dragstart", this.touchstart).bind("drag", this.touchmove).bind("dragend", this.touchend)
  187. $(window).bind("orientationchange resize", function() {
  188. _this.resize(_this);
  189. });
  190. });
  191. }
  192. ;
  193. var touchSlider = {
  194. init: function() {
  195. var _this = this;
  196. $(this).children().css({
  197. "width": this._width + "px",
  198. "overflow": "visible"
  199. });
  200. if (this.opts.flexible)
  201. this._item_w = this._width / this._view;
  202. if (this.opts.roll)
  203. this._len = Math.ceil(this._len / this._view) * this._view;
  204. var page_gap = (this.opts.page > 1 && this.opts.page <= this._len) ? (this.opts.page - 1) * this._item_w : 0;
  205. for (var i = 0; i < this._len; ++i) {
  206. this._pos[i] = this._item_w * i - page_gap;
  207. this._start[i] = this._pos[i];
  208. this._list.eq(i).css({
  209. "float": "none",
  210. "display": "block",
  211. "position": "absolute",
  212. "top": "0",
  213. "left": this._pos[i] + "px",
  214. "width": this._item_w + "px"
  215. });
  216. if (this.opts.supportsCssTransitions && this.opts.transition) {
  217. this._list.eq(i).css({
  218. "-moz-transition": "0ms",
  219. "-moz-transform": "",
  220. "-ms-transition": "0ms",
  221. "-ms-transform": "",
  222. "-webkit-transition": "0ms",
  223. "-webkit-transform": "",
  224. "transition": "0ms",
  225. "transform": ""
  226. });
  227. }
  228. }
  229. if (this.opts.btn_prev && this.opts.btn_next) {
  230. this.opts.btn_prev.bind("click", function() {
  231. _this.animate(1, true);
  232. return false;
  233. })
  234. this.opts.btn_next.bind("click", function() {
  235. _this.animate(-1, true);
  236. return false;
  237. });
  238. }
  239. if (this.opts.paging) {
  240. $(this._list).each(function(i, el) {
  241. var btn_page = _this.opts.paging.eq(i);
  242. btn_page.bind("click", function(e) {
  243. _this.go_page(i, e);
  244. return false;
  245. });
  246. });
  247. }
  248. this.counter();
  249. this.initComplete();
  250. },
  251. initComplete: function() {
  252. if (typeof (this.opts.initComplete) == "function") {
  253. this.opts.initComplete(this);
  254. }
  255. },
  256. resize: function(e) {
  257. if (e.opts.flexible) {
  258. var tmp_w = e._item_w;
  259. e._width = parseInt(e._tg.css("width"));
  260. e._item_w = e._width / e._view;
  261. e._range = e.opts.range * e._width;
  262. for (var i = 0; i < e._len; ++i) {
  263. e._pos[i] = e._pos[i] / tmp_w * e._item_w;
  264. e._start[i] = e._start[i] / tmp_w * e._item_w;
  265. e._list.eq(i).css({
  266. "left": e._pos[i] + "px",
  267. "width": e._item_w + "px"
  268. });
  269. if (this.opts.supportsCssTransitions && this.opts.transition) {
  270. e._list.eq(i).css({
  271. "-moz-transition": "0ms",
  272. "-moz-transform": "",
  273. "-ms-transition": "0ms",
  274. "-ms-transform": "",
  275. "-webkit-transition": "0ms",
  276. "-webkit-transform": "",
  277. "transition": "0ms",
  278. "transform": ""
  279. });
  280. }
  281. }
  282. }
  283. this.counter();
  284. },
  285. touchstart: function(e) {
  286. if ((e.type == "touchstart" && e.originalEvent.touches.length <= 1) || e.type == "dragstart") {
  287. this._startX = e.pageX || e.originalEvent.touches[0].pageX;
  288. this._startY = e.pageY || e.originalEvent.touches[0].pageY;
  289. this._scroll = false;
  290. this._start = [];
  291. for (var i = 0; i < this._len; ++i) {
  292. this._start[i] = this._pos[i];
  293. }
  294. }
  295. },
  296. touchmove: function(e) {
  297. if ((e.type == "touchmove" && e.originalEvent.touches.length <= 1) || e.type == "drag") {
  298. this._left = (e.pageX || e.originalEvent.touches[0].pageX) - this._startX;
  299. this._top = (e.pageY || e.originalEvent.touches[0].pageY) - this._startY;
  300. var w = this._left < 0 ? this._left * -1 : this._left;
  301. var h = this._top < 0 ? this._top * -1 : this._top;
  302. if (w < h || this._scroll) {
  303. this._left = 0;
  304. this._drag = false;
  305. this._scroll = true;
  306. } else {
  307. e.preventDefault();
  308. this._drag = true;
  309. this._scroll = false;
  310. this.position(e);
  311. }
  312. for (var i = 0; i < this._len; ++i) {
  313. var tmp = this._start[i] + this._left;
  314. if (this.opts.supportsCssTransitions && this.opts.transition) {
  315. var trans = "translate3d(" + tmp + "px,0,0)";
  316. this._list.eq(i).css({
  317. "left": "",
  318. "-moz-transition": "0ms",
  319. "-moz-transform": trans,
  320. "-ms-transition": "0ms",
  321. "-ms-transform": trans,
  322. "-webkit-transition": "0ms",
  323. "-webkit-transform": trans,
  324. "transition": "0ms",
  325. "transform": trans
  326. });
  327. } else {
  328. this._list.eq(i).css("left", tmp + "px");
  329. }
  330. this._pos[i] = tmp;
  331. }
  332. }
  333. },
  334. touchend: function(e) {
  335. if ((e.type == "touchend" && e.originalEvent.touches.length <= 1) || e.type == "dragend") {
  336. if (this._scroll) {
  337. this._drag = false;
  338. this._scroll = false;
  339. return false;
  340. }
  341. this.animate(this.direction());
  342. this._drag = false;
  343. this._scroll = false;
  344. }
  345. },
  346. position: function(d) {
  347. var gap = this._view * this._item_w;
  348. if (d == -1 || d == 1) {
  349. this._startX = 0;
  350. this._start = [];
  351. for (var i = 0; i < this._len; ++i) {
  352. this._start[i] = this._pos[i];
  353. }
  354. this._left = d * gap;
  355. } else {
  356. if (this._left > gap)
  357. this._left = gap;
  358. if (this._left < -gap)
  359. this._left = -gap;
  360. }
  361. if (this.opts.roll) {
  362. var tmp_pos = [];
  363. for (var i = 0; i < this._len; ++i) {
  364. tmp_pos[i] = this._pos[i];
  365. }
  366. tmp_pos.sort(function(a, b) {
  367. return a - b;
  368. });
  369. var max_chk = tmp_pos[this._len - this._view];
  370. var p_min = $.inArray(tmp_pos[0], this._pos);
  371. var p_max = $.inArray(max_chk, this._pos);
  372. if (this._view <= 1)
  373. max_chk = this._len - 1;
  374. if (this.opts.multi) {
  375. if ((d == 1 && tmp_pos[0] >= 0) || (this._drag && tmp_pos[0] >= 100)) {
  376. for (var i = 0; i < this._view; ++i,
  377. ++p_min,
  378. ++p_max) {
  379. this._start[p_max] = this._start[p_min] - gap;
  380. this._list.eq(p_max).css("left", this._start[p_max] + "px");
  381. }
  382. } else if ((d == -1 && tmp_pos[0] <= 0) || (this._drag && tmp_pos[0] <= -100)) {
  383. for (var i = 0; i < this._view; ++i,
  384. ++p_min,
  385. ++p_max) {
  386. this._start[p_min] = this._start[p_max] + gap;
  387. this._list.eq(p_min).css("left", this._start[p_min] + "px");
  388. }
  389. }
  390. } else {
  391. if ((d == 1 && tmp_pos[0] >= 0) || (this._drag && tmp_pos[0] > 0)) {
  392. for (var i = 0; i < this._view; ++i,
  393. ++p_min,
  394. ++p_max) {
  395. this._start[p_max] = this._start[p_min] - gap;
  396. this._list.eq(p_max).css("left", this._start[p_max] + "px");
  397. }
  398. } else if ((d == -1 && tmp_pos[max_chk] <= 0) || (this._drag && tmp_pos[max_chk] <= 0)) {
  399. for (var i = 0; i < this._view; ++i,
  400. ++p_min,
  401. ++p_max) {
  402. this._start[p_min] = this._start[p_max] + gap;
  403. this._list.eq(p_min).css("left", this._start[p_min] + "px");
  404. }
  405. }
  406. }
  407. } else {
  408. if (this.limit_chk())
  409. this._left = this._left / 2;
  410. }
  411. },
  412. animate: function(d, btn_click) {
  413. if (this._drag || !this._scroll || btn_click) {
  414. var _this = this;
  415. var speed = this._speed;
  416. if (btn_click)
  417. this.position(d);
  418. var gap = d * (this._item_w * this._view);
  419. if (this._left == 0 || (!this.opts.roll && this.limit_chk()))
  420. gap = 0;
  421. this._list.each(function(i, el) {
  422. _this._pos[i] = _this._start[i] + gap;
  423. if (_this.opts.supportsCssTransitions && _this.opts.transition) {
  424. var transition = speed + "ms";
  425. var transform = "translate3d(" + _this._pos[i] + "px,0,0)";
  426. if (btn_click)
  427. transition = "0ms";
  428. $(this).css({
  429. "left": "",
  430. "-moz-transition": transition,
  431. "-moz-transform": transform,
  432. "-ms-transition": transition,
  433. "-ms-transform": transform,
  434. "-webkit-transition": transition,
  435. "-webkit-transform": transform,
  436. "transition": transition,
  437. "transform": transform
  438. });
  439. } else {
  440. $(this).stop();
  441. $(this).animate({
  442. "left": _this._pos[i] + "px"
  443. }, speed);
  444. }
  445. });
  446. this.counter();
  447. }
  448. },
  449. direction: function() {
  450. var r = 0;
  451. if (this._left < -(this._range))
  452. r = -1;
  453. else if (this._left > this._range)
  454. r = 1;
  455. if (!this._drag || this._scroll)
  456. r = 0;
  457. return r;
  458. },
  459. limit_chk: function() {
  460. var last_p = parseInt((this._len - 1) / this._view) * this._view;
  461. return ((this._start[0] == 0 && this._left > 0) || (this._start[last_p] == 0 && this._left < 0));
  462. },
  463. go_page: function(i, e) {
  464. var crt = ($.inArray(0, this._pos) / this._view) + 1;
  465. var cal = crt - (i + 1);
  466. while (cal != 0) {
  467. if (cal < 0) {
  468. this.animate(-1, true);
  469. cal++;
  470. } else if (cal > 0) {
  471. this.animate(1, true);
  472. cal--;
  473. }
  474. }
  475. },
  476. counter: function() {
  477. if (typeof (this.opts.counter) == "function") {
  478. var param = {
  479. total: Math.ceil(this._len / this._view),
  480. current: ($.inArray(0, this._pos) / this._view) + 1
  481. };
  482. this.opts.counter(param);
  483. }
  484. }
  485. };
  486. }
  487. )(jQuery);