You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

401 lines
13 KiB

  1. 'use strict';
  2. exports.__esModule = true;
  3. var _trackHelper = require('./trackHelper');
  4. var _helpers = require('./helpers');
  5. var _helpers2 = _interopRequireDefault(_helpers);
  6. var _objectAssign = require('object-assign');
  7. var _objectAssign2 = _interopRequireDefault(_objectAssign);
  8. var _reactDom = require('react-dom');
  9. var _reactDom2 = _interopRequireDefault(_reactDom);
  10. var _trackUtils = require('../utils/trackUtils');
  11. var _innerSliderUtils = require('../utils/innerSliderUtils');
  12. function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
  13. var EventHandlers = {
  14. // Event handler for previous and next
  15. // gets called if slide is changed via arrows or dots but not swiping/dragging
  16. changeSlide: function changeSlide(options) {
  17. var indexOffset, previousInt, slideOffset, unevenOffset, targetSlide;
  18. var _props = this.props,
  19. slidesToScroll = _props.slidesToScroll,
  20. slidesToShow = _props.slidesToShow,
  21. centerMode = _props.centerMode,
  22. rtl = _props.rtl;
  23. var _state = this.state,
  24. slideCount = _state.slideCount,
  25. currentSlide = _state.currentSlide;
  26. unevenOffset = slideCount % slidesToScroll !== 0;
  27. indexOffset = unevenOffset ? 0 : (slideCount - currentSlide) % slidesToScroll;
  28. if (options.message === 'previous') {
  29. slideOffset = indexOffset === 0 ? slidesToScroll : slidesToShow - indexOffset;
  30. targetSlide = currentSlide - slideOffset;
  31. if (this.props.lazyLoad && !this.props.infinite) {
  32. previousInt = currentSlide - slideOffset;
  33. targetSlide = previousInt === -1 ? slideCount - 1 : previousInt;
  34. }
  35. } else if (options.message === 'next') {
  36. slideOffset = indexOffset === 0 ? slidesToScroll : indexOffset;
  37. targetSlide = currentSlide + slideOffset;
  38. if (this.props.lazyLoad && !this.props.infinite) {
  39. targetSlide = (currentSlide + slidesToScroll) % slideCount + indexOffset;
  40. }
  41. } else if (options.message === 'dots') {
  42. // Click on dots
  43. targetSlide = options.index * options.slidesToScroll;
  44. if (targetSlide === options.currentSlide) {
  45. return;
  46. }
  47. } else if (options.message === 'children') {
  48. // Click on the slides
  49. targetSlide = options.index;
  50. if (targetSlide === options.currentSlide) {
  51. return;
  52. }
  53. if (this.props.infinite) {
  54. var direction = (0, _trackUtils.siblingDirection)({ currentSlide: currentSlide, targetSlide: targetSlide, slidesToShow: slidesToShow, centerMode: centerMode, slideCount: slideCount, rtl: rtl });
  55. if (targetSlide > options.currentSlide && direction === 'left') {
  56. targetSlide = targetSlide - slideCount;
  57. } else if (targetSlide < options.currentSlide && direction === 'right') {
  58. targetSlide = targetSlide + slideCount;
  59. }
  60. }
  61. } else if (options.message === 'index') {
  62. targetSlide = Number(options.index);
  63. if (targetSlide === options.currentSlide) {
  64. return;
  65. }
  66. }
  67. this.slideHandler(targetSlide);
  68. },
  69. // Accessiblity handler for previous and next
  70. keyHandler: function keyHandler(e) {
  71. //Dont slide if the cursor is inside the form fields and arrow keys are pressed
  72. if (!e.target.tagName.match('TEXTAREA|INPUT|SELECT')) {
  73. if (e.keyCode === 37 && this.props.accessibility === true) {
  74. this.changeSlide({
  75. message: this.props.rtl === true ? 'next' : 'previous'
  76. });
  77. } else if (e.keyCode === 39 && this.props.accessibility === true) {
  78. this.changeSlide({
  79. message: this.props.rtl === true ? 'previous' : 'next'
  80. });
  81. }
  82. }
  83. },
  84. // Focus on selecting a slide (click handler on track)
  85. selectHandler: function selectHandler(options) {
  86. this.changeSlide(options);
  87. },
  88. // invoked when swiping/dragging starts (just once)
  89. swipeStart: function swipeStart(e) {
  90. if (e.target.tagName === 'IMG') {
  91. e.preventDefault();
  92. }
  93. var touches, posX, posY;
  94. // the condition after or looked redundant
  95. if (this.props.swipe === false) {
  96. // || ('ontouchend' in document && this.props.swipe === false)) {
  97. return;
  98. } else if (this.props.draggable === false && e.type.indexOf('mouse') !== -1) {
  99. return;
  100. }
  101. posX = e.touches !== undefined ? e.touches[0].pageX : e.clientX;
  102. posY = e.touches !== undefined ? e.touches[0].pageY : e.clientY;
  103. this.setState({
  104. dragging: true,
  105. touchObject: {
  106. startX: posX,
  107. startY: posY,
  108. curX: posX,
  109. curY: posY
  110. }
  111. });
  112. },
  113. // continuous invokation while swiping/dragging is going on
  114. swipeMove: function swipeMove(e) {
  115. if (!this.state.dragging) {
  116. e.preventDefault();
  117. return;
  118. }
  119. if (this.state.scrolling) {
  120. return;
  121. }
  122. if (this.state.animating) {
  123. e.preventDefault();
  124. return;
  125. }
  126. if (this.props.vertical && this.props.swipeToSlide && this.props.verticalSwiping) {
  127. e.preventDefault();
  128. }
  129. var swipeLeft;
  130. var curLeft, positionOffset;
  131. var touchObject = this.state.touchObject;
  132. curLeft = (0, _trackHelper.getTrackLeft)((0, _objectAssign2.default)({
  133. slideIndex: this.state.currentSlide,
  134. trackRef: this.track
  135. }, this.props, this.state));
  136. touchObject.curX = e.touches ? e.touches[0].pageX : e.clientX;
  137. touchObject.curY = e.touches ? e.touches[0].pageY : e.clientY;
  138. touchObject.swipeLength = Math.round(Math.sqrt(Math.pow(touchObject.curX - touchObject.startX, 2)));
  139. var verticalSwipeLength = Math.round(Math.sqrt(Math.pow(touchObject.curY - touchObject.startY, 2)));
  140. if (!this.props.verticalSwiping && !this.state.swiping && verticalSwipeLength > 10) {
  141. this.setState({
  142. scrolling: true
  143. });
  144. return;
  145. }
  146. if (this.props.verticalSwiping) {
  147. touchObject.swipeLength = verticalSwipeLength;
  148. }
  149. positionOffset = (this.props.rtl === false ? 1 : -1) * (touchObject.curX > touchObject.startX ? 1 : -1);
  150. if (this.props.verticalSwiping) {
  151. positionOffset = touchObject.curY > touchObject.startY ? 1 : -1;
  152. }
  153. var currentSlide = this.state.currentSlide;
  154. var dotCount = Math.ceil(this.state.slideCount / this.props.slidesToScroll); // this might not be correct, using getDotCount may be more accurate
  155. var swipeDirection = (0, _innerSliderUtils.getSwipeDirection)(this.state.touchObject, this.props.verticalSwiping);
  156. var touchSwipeLength = touchObject.swipeLength;
  157. if (this.props.infinite === false) {
  158. if (currentSlide === 0 && swipeDirection === 'right' || currentSlide + 1 >= dotCount && swipeDirection === 'left') {
  159. touchSwipeLength = touchObject.swipeLength * this.props.edgeFriction;
  160. if (this.state.edgeDragged === false && this.props.edgeEvent) {
  161. this.props.edgeEvent(swipeDirection);
  162. this.setState({ edgeDragged: true });
  163. }
  164. }
  165. }
  166. if (this.state.swiped === false && this.props.swipeEvent) {
  167. this.props.swipeEvent(swipeDirection);
  168. this.setState({ swiped: true });
  169. }
  170. if (!this.props.vertical) {
  171. if (!this.props.rtl) {
  172. swipeLeft = curLeft + touchSwipeLength * positionOffset;
  173. } else {
  174. swipeLeft = curLeft - touchSwipeLength * positionOffset;
  175. }
  176. } else {
  177. swipeLeft = curLeft + touchSwipeLength * (this.state.listHeight / this.state.listWidth) * positionOffset;
  178. }
  179. if (this.props.verticalSwiping) {
  180. swipeLeft = curLeft + touchSwipeLength * positionOffset;
  181. }
  182. this.setState({
  183. touchObject: touchObject,
  184. swipeLeft: swipeLeft,
  185. trackStyle: (0, _trackHelper.getTrackCSS)((0, _objectAssign2.default)({ left: swipeLeft }, this.props, this.state))
  186. });
  187. if (Math.abs(touchObject.curX - touchObject.startX) < Math.abs(touchObject.curY - touchObject.startY) * 0.8) {
  188. return;
  189. }
  190. if (touchObject.swipeLength > 10) {
  191. this.setState({
  192. swiping: true
  193. });
  194. e.preventDefault();
  195. }
  196. },
  197. getNavigableIndexes: function getNavigableIndexes() {
  198. var max = void 0;
  199. var breakPoint = 0;
  200. var counter = 0;
  201. var indexes = [];
  202. if (!this.props.infinite) {
  203. max = this.state.slideCount;
  204. } else {
  205. breakPoint = this.props.slidesToShow * -1;
  206. counter = this.props.slidesToShow * -1;
  207. max = this.state.slideCount * 2;
  208. }
  209. while (breakPoint < max) {
  210. indexes.push(breakPoint);
  211. breakPoint = counter + this.props.slidesToScroll;
  212. counter += this.props.slidesToScroll <= this.props.slidesToShow ? this.props.slidesToScroll : this.props.slidesToShow;
  213. }
  214. return indexes;
  215. },
  216. checkNavigable: function checkNavigable(index) {
  217. var navigables = this.getNavigableIndexes();
  218. var prevNavigable = 0;
  219. if (index > navigables[navigables.length - 1]) {
  220. index = navigables[navigables.length - 1];
  221. } else {
  222. for (var n in navigables) {
  223. if (index < navigables[n]) {
  224. index = prevNavigable;
  225. break;
  226. }
  227. prevNavigable = navigables[n];
  228. }
  229. }
  230. return index;
  231. },
  232. getSlideCount: function getSlideCount() {
  233. var _this = this;
  234. var centerOffset = this.props.centerMode ? this.state.slideWidth * Math.floor(this.props.slidesToShow / 2) : 0;
  235. if (this.props.swipeToSlide) {
  236. var swipedSlide = void 0;
  237. var slickList = _reactDom2.default.findDOMNode(this.list);
  238. var slides = slickList.querySelectorAll('.slick-slide');
  239. Array.from(slides).every(function (slide) {
  240. if (!_this.props.vertical) {
  241. if (slide.offsetLeft - centerOffset + (0, _innerSliderUtils.getWidth)(slide) / 2 > _this.state.swipeLeft * -1) {
  242. swipedSlide = slide;
  243. return false;
  244. }
  245. } else {
  246. if (slide.offsetTop + (0, _innerSliderUtils.getHeight)(slide) / 2 > _this.state.swipeLeft * -1) {
  247. swipedSlide = slide;
  248. return false;
  249. }
  250. }
  251. return true;
  252. });
  253. if (!swipedSlide) {
  254. return 0;
  255. }
  256. var currentIndex = this.props.rtl === true ? this.state.slideCount - this.state.currentSlide : this.state.currentSlide;
  257. var slidesTraversed = Math.abs(swipedSlide.dataset.index - currentIndex) || 1;
  258. return slidesTraversed;
  259. } else {
  260. return this.props.slidesToScroll;
  261. }
  262. },
  263. swipeEnd: function swipeEnd(e) {
  264. if (!this.state.dragging) {
  265. if (this.props.swipe) {
  266. e.preventDefault();
  267. }
  268. return;
  269. }
  270. var touchObject = this.state.touchObject;
  271. var minSwipe = this.state.listWidth / this.props.touchThreshold;
  272. var swipeDirection = (0, _innerSliderUtils.getSwipeDirection)(touchObject, this.props.verticalSwiping);
  273. if (this.props.verticalSwiping) {
  274. minSwipe = this.state.listHeight / this.props.touchThreshold;
  275. }
  276. var wasScrolling = this.state.scrolling;
  277. // reset the state of touch related state variables.
  278. this.setState({
  279. dragging: false,
  280. edgeDragged: false,
  281. scrolling: false,
  282. swiping: false,
  283. swiped: false,
  284. swipeLeft: null,
  285. touchObject: {}
  286. });
  287. if (wasScrolling) {
  288. return;
  289. }
  290. // Fix for #13
  291. if (!touchObject.swipeLength) {
  292. return;
  293. }
  294. if (touchObject.swipeLength > minSwipe) {
  295. e.preventDefault();
  296. if (this.props.onSwipe) {
  297. this.props.onSwipe(swipeDirection);
  298. }
  299. var slideCount = void 0,
  300. newSlide = void 0;
  301. switch (swipeDirection) {
  302. case 'left':
  303. case 'up':
  304. newSlide = this.state.currentSlide + this.getSlideCount();
  305. slideCount = this.props.swipeToSlide ? this.checkNavigable(newSlide) : newSlide;
  306. this.setState({ currentDirection: 0 });
  307. break;
  308. case 'right':
  309. case 'down':
  310. newSlide = this.state.currentSlide - this.getSlideCount();
  311. slideCount = this.props.swipeToSlide ? this.checkNavigable(newSlide) : newSlide;
  312. this.setState({ currentDirection: 1 });
  313. break;
  314. default:
  315. slideCount = this.state.currentSlide;
  316. }
  317. this.slideHandler(slideCount);
  318. } else {
  319. // Adjust the track back to it's original position.
  320. var currentLeft = (0, _trackHelper.getTrackLeft)((0, _objectAssign2.default)({
  321. slideIndex: this.state.currentSlide,
  322. trackRef: this.track
  323. }, this.props, this.state));
  324. this.setState({
  325. trackStyle: (0, _trackHelper.getTrackAnimateCSS)((0, _objectAssign2.default)({ left: currentLeft }, this.props, this.state))
  326. });
  327. }
  328. },
  329. onInnerSliderEnter: function onInnerSliderEnter(e) {
  330. if (this.props.autoplay && this.props.pauseOnHover) {
  331. this.pause();
  332. }
  333. },
  334. onInnerSliderOver: function onInnerSliderOver(e) {
  335. if (this.props.autoplay && this.props.pauseOnHover) {
  336. this.pause();
  337. }
  338. },
  339. onInnerSliderLeave: function onInnerSliderLeave(e) {
  340. if (this.props.autoplay && this.props.pauseOnHover) {
  341. this.autoPlay();
  342. }
  343. }
  344. };
  345. exports.default = EventHandlers;