UNPKG

4.03 kBJavaScriptView Raw
1import { getWindow, getDocument } from 'ssr-window';
2import $ from '../../shared/dom.js';
3import { now } from '../../shared/utils.js'; // Modified from https://stackoverflow.com/questions/54520554/custom-element-getrootnode-closest-function-crossing-multiple-parent-shadowd
4
5function closestElement(selector, base = this) {
6 function __closestFrom(el) {
7 if (!el || el === getDocument() || el === getWindow()) return null;
8 if (el.assignedSlot) el = el.assignedSlot;
9 const found = el.closest(selector);
10 return found || __closestFrom(el.getRootNode().host);
11 }
12
13 return __closestFrom(base);
14}
15
16export default function onTouchStart(event) {
17 const swiper = this;
18 const document = getDocument();
19 const window = getWindow();
20 const data = swiper.touchEventsData;
21 const {
22 params,
23 touches,
24 enabled
25 } = swiper;
26 if (!enabled) return;
27
28 if (swiper.animating && params.preventInteractionOnTransition) {
29 return;
30 }
31
32 if (!swiper.animating && params.cssMode && params.loop) {
33 swiper.loopFix();
34 }
35
36 let e = event;
37 if (e.originalEvent) e = e.originalEvent;
38 let $targetEl = $(e.target);
39
40 if (params.touchEventsTarget === 'wrapper') {
41 if (!$targetEl.closest(swiper.wrapperEl).length) return;
42 }
43
44 data.isTouchEvent = e.type === 'touchstart';
45 if (!data.isTouchEvent && 'which' in e && e.which === 3) return;
46 if (!data.isTouchEvent && 'button' in e && e.button > 0) return;
47 if (data.isTouched && data.isMoved) return; // change target el for shadow root component
48
49 const swipingClassHasValue = !!params.noSwipingClass && params.noSwipingClass !== '';
50
51 if (swipingClassHasValue && e.target && e.target.shadowRoot && event.path && event.path[0]) {
52 $targetEl = $(event.path[0]);
53 }
54
55 const noSwipingSelector = params.noSwipingSelector ? params.noSwipingSelector : `.${params.noSwipingClass}`;
56 const isTargetShadow = !!(e.target && e.target.shadowRoot); // use closestElement for shadow root element to get the actual closest for nested shadow root element
57
58 if (params.noSwiping && (isTargetShadow ? closestElement(noSwipingSelector, e.target) : $targetEl.closest(noSwipingSelector)[0])) {
59 swiper.allowClick = true;
60 return;
61 }
62
63 if (params.swipeHandler) {
64 if (!$targetEl.closest(params.swipeHandler)[0]) return;
65 }
66
67 touches.currentX = e.type === 'touchstart' ? e.targetTouches[0].pageX : e.pageX;
68 touches.currentY = e.type === 'touchstart' ? e.targetTouches[0].pageY : e.pageY;
69 const startX = touches.currentX;
70 const startY = touches.currentY; // Do NOT start if iOS edge swipe is detected. Otherwise iOS app cannot swipe-to-go-back anymore
71
72 const edgeSwipeDetection = params.edgeSwipeDetection || params.iOSEdgeSwipeDetection;
73 const edgeSwipeThreshold = params.edgeSwipeThreshold || params.iOSEdgeSwipeThreshold;
74
75 if (edgeSwipeDetection && (startX <= edgeSwipeThreshold || startX >= window.innerWidth - edgeSwipeThreshold)) {
76 if (edgeSwipeDetection === 'prevent') {
77 event.preventDefault();
78 } else {
79 return;
80 }
81 }
82
83 Object.assign(data, {
84 isTouched: true,
85 isMoved: false,
86 allowTouchCallbacks: true,
87 isScrolling: undefined,
88 startMoving: undefined
89 });
90 touches.startX = startX;
91 touches.startY = startY;
92 data.touchStartTime = now();
93 swiper.allowClick = true;
94 swiper.updateSize();
95 swiper.swipeDirection = undefined;
96 if (params.threshold > 0) data.allowThresholdMove = false;
97
98 if (e.type !== 'touchstart') {
99 let preventDefault = true;
100 if ($targetEl.is(data.focusableElements)) preventDefault = false;
101
102 if (document.activeElement && $(document.activeElement).is(data.focusableElements) && document.activeElement !== $targetEl[0]) {
103 document.activeElement.blur();
104 }
105
106 const shouldPreventDefault = preventDefault && swiper.allowTouchMove && params.touchStartPreventDefault;
107
108 if ((params.touchStartForcePreventDefault || shouldPreventDefault) && !$targetEl[0].isContentEditable) {
109 e.preventDefault();
110 }
111 }
112
113 swiper.emit('touchStart', e);
114}
\No newline at end of file