expand-slide.js 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418
  1. function ExpandSlide(el, cfg) {
  2. return new ExpandSlide.prototype.init(el, cfg);
  3. }
  4. ExpandSlide.prototype = {
  5. constructor: ExpandSlide,
  6. init: function (el, cfg) {
  7. var dfs = {
  8. autoplay: false,
  9. duration: 500,
  10. nextBtn: null,
  11. prevBtn: null,
  12. wrapper: '.swiper-wrapper',
  13. panels: '.swiper-slide',
  14. pagination: '.pagination',
  15. callback: function () {}
  16. }
  17. if (!el) {
  18. throw Error("请设置wrapper");
  19. }
  20. this.cfg = $.extend(dfs, cfg);
  21. this.container = $(el);
  22. this.wrapper = el.find(this.cfg.wrapper);
  23. this.cachePanels = this.wrapper.find(this.cfg.panels);
  24. this.activeIndex = 0;
  25. this.initWrapper();
  26. },
  27. initWrapper: function () {
  28. var self = this,
  29. items = this.wrapper.find(this.cfg.panels),
  30. len = items.length,
  31. itemWidth = items.eq(0).width();
  32. this.itemCount = len;
  33. this.itemWidth = itemWidth;
  34. if (len < 3) {
  35. //throw Error("slideItem小于3个");
  36. return;
  37. }
  38. items.width(itemWidth);
  39. this.wrapper.width((len + 4) * itemWidth);
  40. //拷贝节点
  41. this.wrapper.prepend(items.eq(len - 1).clone());
  42. this.wrapper.prepend(items.eq(len - 2).clone());
  43. this.wrapper.append(items.eq(0).clone());
  44. this.wrapper.append(items.eq(1).clone());
  45. this.setTranslate(this.wrapper[0], {
  46. x: -2 * itemWidth
  47. }, 0);
  48. this.createPagination(len);
  49. this.bind();
  50. },
  51. createPagination: function (len) {
  52. var tpl = '',
  53. cls = '';
  54. for (var i = 0; i < len; i++) {
  55. if (i == 0) {
  56. cls = 'swiper-visible-switch swiper-active-switch';
  57. } else {
  58. cls = '';
  59. }
  60. tpl += '<span class="swiper-pagination-switch ' + cls + '"></span>';
  61. }
  62. this.container.find(this.cfg.pagination).append(tpl);
  63. },
  64. bind: function () {
  65. var self = this;
  66. var desktopEvents = ['mousedown', 'mousemove', 'mouseup'];
  67. if (self.browser.ie10) desktopEvents = ['MSPointerDown', 'MSPointerMove', 'MSPointerUp'];
  68. if (self.browser.ie11) desktopEvents = ['pointerdown', 'pointermove', 'pointerup'];
  69. self.touchEvents = {
  70. touchStart: self.support.touch || !self.cfg.simulateTouch ? 'touchstart' : desktopEvents[0],
  71. touchMove: self.support.touch || !self.cfg.simulateTouch ? 'touchmove' : desktopEvents[1],
  72. touchEnd: self.support.touch || !self.cfg.simulateTouch ? 'touchend' : desktopEvents[2]
  73. };
  74. var bind = self.addEventListener,
  75. delegateTarget = self.wrapper[0];
  76. //Touch Events
  77. if (!(self.browser.ie10 || self.browser.ie11)) {
  78. if (self.support.touch) {
  79. bind(delegateTarget, 'touchstart', onTouchStart);
  80. bind(delegateTarget, 'touchmove', onTouchMove);
  81. bind(delegateTarget, 'touchend', onTouchEnd);
  82. } else if (self.cfg.simulateTouch) {
  83. self.wrapper.on('mousedown', onTouchStart);
  84. $(document).on('mousemove', onTouchMove);
  85. $(document).on('mouseup', onTouchEnd);
  86. }
  87. } else {
  88. self.wrapper.on(self.touchEvents.touchStart, onTouchStart);
  89. $(document).on(self.touchEvents.touchMove, onTouchMove);
  90. $(document).on(self.touchEvents.touchEnd, onTouchEnd);
  91. }
  92. self.touches = {};
  93. function onTouchStart(e) {
  94. self.touches.startLeft = self.get3DTranslateLeft(self.wrapper[0]);
  95. self.touches.dragable = true;
  96. if (!self.support.touch) {
  97. self.touches.startX = e.pageX;
  98. self.touches.startY = e.pageY;
  99. } else {
  100. self.touches.startX = e.targetTouches[0].pageX;
  101. self.touches.startY = e.targetTouches[0].pageY;
  102. }
  103. self.stopPlay()
  104. //e.preventDefault();
  105. }
  106. function onTouchMove(e) {
  107. if (self.touches.dragable) {
  108. var curX = self.touches.startLeft;
  109. var toX = 0,
  110. movedX = 0,
  111. movedY = 0;
  112. if (!self.support.touch) {
  113. // toX = curX-self.touches.startX+e.pageX;
  114. movedX = self.touches.startX - e.pageX;
  115. movedY = self.touches.startY - e.pageY;
  116. } else {
  117. // toX = curX-self.touches.startX+e.targetTouches[0].pageX;
  118. movedX = self.touches.startX - e.targetTouches[0].pageX;
  119. movedY = self.touches.startY - e.targetTouches[0].pageY;
  120. }
  121. if (Math.abs(movedY) < Math.abs(movedX)) {
  122. toX = curX - movedX;
  123. self.setTranslate(self.wrapper[0], {
  124. x: toX
  125. }, 0);
  126. e.preventDefault();
  127. }
  128. }
  129. }
  130. function onTouchEnd(e) {
  131. if (!self.support.touch) {
  132. self.touches.startX = e.pageX
  133. } else {
  134. self.touches.startX = e.changedTouches[0].pageX;
  135. }
  136. self.touches.dragable = false;
  137. var curLeft = self.get3DTranslateLeft(self.wrapper[0]);
  138. if (self.touches.startLeft - curLeft < -self.itemWidth / 10) {
  139. self.prev();
  140. } else if (self.touches.startLeft - curLeft > self.itemWidth / 10) {
  141. self.next();
  142. } else {
  143. self.restore();
  144. }
  145. self.startPlay();
  146. e.preventDefault();
  147. }
  148. this.cfg.nextBtn.click(function () {
  149. self.next();
  150. }).on('mouseenter', function () {
  151. self.stopPlay()
  152. }).on('mouseleave', function () {
  153. if (self.cfg.autoplay) {
  154. self.startPlay();
  155. }
  156. })
  157. this.cfg.prevBtn.click(function () {
  158. self.prev();
  159. }).on('mouseenter', function () {
  160. self.stopPlay()
  161. }).on('mouseleave', function () {
  162. if (self.cfg.autoplay) {
  163. self.startPlay();
  164. }
  165. })
  166. this.wrapper.on('mouseenter', function () {
  167. self.stopPlay()
  168. }).on('mouseleave', function () {
  169. if (self.cfg.autoplay) {
  170. self.startPlay();
  171. }
  172. })
  173. this.container.find(self.cfg.pagination).on('click', 'span', function () {
  174. self.swipeTo($(this).index())
  175. return false;
  176. })
  177. if (this.cfg.autoplay) {
  178. this.startPlay();
  179. }
  180. },
  181. startPlay: function () {
  182. var self = this;
  183. this.stopPlay();
  184. this.autoInterval = setInterval(function () {
  185. self.next();
  186. }, this.cfg.autoplay * 1000)
  187. },
  188. stopPlay: function () {
  189. clearInterval(this.autoInterval);
  190. },
  191. restore: function () {
  192. var self = this;
  193. this.setTranslate(this.wrapper[0], {
  194. x: -(2 + this.activeIndex) * this.itemWidth
  195. }, this.cfg.duration, function () {});
  196. },
  197. moving: false,
  198. next: function () {
  199. var self = this;
  200. if (this.moving) return;
  201. this.moving = true;
  202. this.activeIndex++;
  203. this.doSwipe();
  204. },
  205. prev: function () {
  206. var self = this;
  207. if (this.moving) return;
  208. this.moving = true;
  209. this.activeIndex--;
  210. this.doSwipe();
  211. },
  212. swipeTo: function (activeIndex) {
  213. var self = this;
  214. if (this.moving) return;
  215. this.moving = true;
  216. this.activeIndex = activeIndex;
  217. this.doSwipe();
  218. },
  219. doSwipe: function () {
  220. var self = this;
  221. this.setTranslate(this.wrapper[0], {
  222. x: -(2 + this.activeIndex) * this.itemWidth
  223. }, this.cfg.duration, function () {
  224. if (self.activeIndex <= -1) {
  225. self.activeIndex = self.itemCount - 1;
  226. self.setTranslate(self.wrapper[0], {
  227. x: -(2 + self.activeIndex) * self.itemWidth
  228. }, 0);
  229. }
  230. if (self.activeIndex >= self.itemCount) {
  231. self.activeIndex = 0;
  232. self.setTranslate(self.wrapper[0], {
  233. x: -(2 + self.activeIndex) * self.itemWidth
  234. }, 0);
  235. }
  236. self.moving = false;
  237. self.container.find(self.cfg.pagination).find('span').removeClass('swiper-visible-switch swiper-active-switch').eq(self.activeIndex).addClass('swiper-visible-switch swiper-active-switch');
  238. self.cfg.callback(self);
  239. });
  240. },
  241. wrapperTransitionEnd: function (callback) {
  242. 'use strict';
  243. var a = this,
  244. el = a.wrapper[0],
  245. events = ['webkitTransitionEnd', 'transitionend', 'oTransitionEnd', 'MSTransitionEnd', 'msTransitionEnd'],
  246. i;
  247. function fireCallBack(e) {
  248. if (e.target !== el) return;
  249. callback(a);
  250. for (i = 0; i < events.length; i++) {
  251. a.removeEventListener(el, events[i], fireCallBack);
  252. }
  253. }
  254. if (callback) {
  255. for (i = 0; i < events.length; i++) {
  256. this.addEventListener(el, events[i], fireCallBack);
  257. }
  258. }
  259. },
  260. setTranslate: function (el, translate, duration, fcallback) {
  261. 'use strict';
  262. var callback = fcallback || function () {};
  263. var es = el.style;
  264. var pos = {
  265. x: translate.x || 0,
  266. y: translate.y || 0,
  267. z: translate.z || 0
  268. };
  269. this.setTransition(el, duration);
  270. var transformString = this.support.transforms3d ? 'translate3d(' + (pos.x) + 'px,' + (pos.y) + 'px,' + (pos.z) + 'px)' : 'translate(' + (pos.x) + 'px,' + (pos.y) + 'px)';
  271. if (this.support.transforms) {
  272. es.webkitTransform = es.MsTransform = es.msTransform = es.MozTransform = es.OTransform = es.transform = transformString;
  273. }
  274. //alert(this.support.transforms)
  275. if (!this.support.transforms) {
  276. $(el).animate({
  277. left: pos.x,
  278. top: pos.y
  279. }, duration, callback)
  280. } else {
  281. if (duration) {
  282. this.wrapperTransitionEnd(function () {
  283. callback()
  284. })
  285. } else {
  286. callback()
  287. }
  288. }
  289. },
  290. get3DTranslateLeft: function (el) {
  291. 'use strict';
  292. var es = el.style;
  293. if (!this.support.transforms) {
  294. return $(el).css('left');
  295. } else {
  296. var translateStr = es.webkitTransform || es.MsTransform || es.msTransform || es.MozTransform || es.OTransform || es.transform;
  297. return translateStr.match(/translate3d\((-*\d*)px/)[1];
  298. }
  299. },
  300. setTransition: function (el, duration) {
  301. 'use strict';
  302. var es = el.style;
  303. es.webkitTransitionDuration = es.MsTransitionDuration = es.msTransitionDuration = es.MozTransitionDuration = es.OTransitionDuration = es.transitionDuration = duration + 'ms';
  304. },
  305. support: {
  306. touch: (window.Modernizr && Modernizr.touch === true) || (function () {
  307. 'use strict';
  308. return !!(('ontouchstart' in window) || window.DocumentTouch && document instanceof DocumentTouch);
  309. })(),
  310. transforms3d: (window.Modernizr && Modernizr.csstransforms3d === true) || (function () {
  311. 'use strict';
  312. var div = document.createElement('div').style;
  313. var ret = ('webkitPerspective' in div || 'MozPerspective' in div || 'OPerspective' in div || 'MsPerspective' in div || 'perspective' in div);
  314. ret = !$.browser.msie || ($.browser.msie && Number($.browser.version) > 9);
  315. return ret;
  316. })(),
  317. transforms: (window.Modernizr && Modernizr.csstransforms === true) || (function () {
  318. 'use strict';
  319. var div = document.createElement('div').style;
  320. var ret = ('transform' in div || 'WebkitTransform' in div || 'MozTransform' in div || 'msTransform' in div || 'MsTransform' in div || 'OTransform' in div);
  321. ret = !$.browser.msie || ($.browser.msie && Number($.browser.version) > 9);
  322. return ret;
  323. })(),
  324. transitions: (window.Modernizr && Modernizr.csstransitions === true) || (function () {
  325. 'use strict';
  326. var div = document.createElement('div').style;
  327. var ret = ('transition' in div || 'WebkitTransition' in div || 'MozTransition' in div || 'msTransition' in div || 'MsTransition' in div || 'OTransition' in div);
  328. ret = !$.browser.msie || ($.browser.msie && Number($.browser.version) > 9);
  329. return ret;
  330. })(),
  331. classList: (function () {
  332. 'use strict';
  333. var div = document.createElement('div').style;
  334. return 'classList' in div;
  335. })()
  336. },
  337. browser: {
  338. ie8: (function () {
  339. 'use strict';
  340. var rv = -1; // Return value assumes failure.
  341. if (navigator.appName === 'Microsoft Internet Explorer') {
  342. var ua = navigator.userAgent;
  343. var re = new RegExp(/MSIE ([0-9]{1,}[\.0-9]{0,})/);
  344. if (re.exec(ua) !== null)
  345. rv = parseFloat(RegExp.$1);
  346. }
  347. return rv !== -1 && rv < 9;
  348. })(),
  349. ie10: window.navigator.msPointerEnabled,
  350. ie11: window.navigator.pointerEnabled
  351. },
  352. addEventListener: function (el, event, listener, useCapture) {
  353. 'use strict';
  354. if (typeof useCapture === 'undefined') {
  355. useCapture = false;
  356. }
  357. if (el.addEventListener) {
  358. el.addEventListener(event, listener, useCapture);
  359. } else if (el.attachEvent) {
  360. el.attachEvent('on' + event, listener);
  361. }
  362. },
  363. removeEventListener: function (el, event, listener, useCapture) {
  364. 'use strict';
  365. if (typeof useCapture === 'undefined') {
  366. useCapture = false;
  367. }
  368. if (el.removeEventListener) {
  369. el.removeEventListener(event, listener, useCapture);
  370. } else if (el.detachEvent) {
  371. el.detachEvent('on' + event, listener);
  372. }
  373. }
  374. }
  375. ExpandSlide.prototype.init.prototype = ExpandSlide.prototype;