123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112 |
- import { getWindow, getDocument } from 'ssr-window';
- import { now } from '../../shared/utils.js';
- // Modified from https://stackoverflow.com/questions/54520554/custom-element-getrootnode-closest-function-crossing-multiple-parent-shadowd
- function closestElement(selector, base = this) {
- function __closestFrom(el) {
- if (!el || el === getDocument() || el === getWindow()) return null;
- if (el.assignedSlot) el = el.assignedSlot;
- const found = el.closest(selector);
- if (!found && !el.getRootNode) {
- return null;
- }
- return found || __closestFrom(el.getRootNode().host);
- }
- return __closestFrom(base);
- }
- export default function onTouchStart(event) {
- const swiper = this;
- const document = getDocument();
- const window = getWindow();
- const data = swiper.touchEventsData;
- data.evCache.push(event);
- const {
- params,
- touches,
- enabled
- } = swiper;
- if (!enabled) return;
- if (!params.simulateTouch && event.pointerType === 'mouse') return;
- if (swiper.animating && params.preventInteractionOnTransition) {
- return;
- }
- if (!swiper.animating && params.cssMode && params.loop) {
- swiper.loopFix();
- }
- let e = event;
- if (e.originalEvent) e = e.originalEvent;
- let targetEl = e.target;
- if (params.touchEventsTarget === 'wrapper') {
- if (!swiper.wrapperEl.contains(targetEl)) return;
- }
- if ('which' in e && e.which === 3) return;
- if ('button' in e && e.button > 0) return;
- if (data.isTouched && data.isMoved) return;
- // change target el for shadow root component
- const swipingClassHasValue = !!params.noSwipingClass && params.noSwipingClass !== '';
- // eslint-disable-next-line
- const eventPath = event.composedPath ? event.composedPath() : event.path;
- if (swipingClassHasValue && e.target && e.target.shadowRoot && eventPath) {
- targetEl = eventPath[0];
- }
- const noSwipingSelector = params.noSwipingSelector ? params.noSwipingSelector : `.${params.noSwipingClass}`;
- const isTargetShadow = !!(e.target && e.target.shadowRoot);
- // use closestElement for shadow root element to get the actual closest for nested shadow root element
- if (params.noSwiping && (isTargetShadow ? closestElement(noSwipingSelector, targetEl) : targetEl.closest(noSwipingSelector))) {
- swiper.allowClick = true;
- return;
- }
- if (params.swipeHandler) {
- if (!targetEl.closest(params.swipeHandler)) return;
- }
- touches.currentX = e.pageX;
- touches.currentY = e.pageY;
- const startX = touches.currentX;
- const startY = touches.currentY;
- // Do NOT start if iOS edge swipe is detected. Otherwise iOS app cannot swipe-to-go-back anymore
- const edgeSwipeDetection = params.edgeSwipeDetection || params.iOSEdgeSwipeDetection;
- const edgeSwipeThreshold = params.edgeSwipeThreshold || params.iOSEdgeSwipeThreshold;
- if (edgeSwipeDetection && (startX <= edgeSwipeThreshold || startX >= window.innerWidth - edgeSwipeThreshold)) {
- if (edgeSwipeDetection === 'prevent') {
- event.preventDefault();
- } else {
- return;
- }
- }
- Object.assign(data, {
- isTouched: true,
- isMoved: false,
- allowTouchCallbacks: true,
- isScrolling: undefined,
- startMoving: undefined
- });
- touches.startX = startX;
- touches.startY = startY;
- data.touchStartTime = now();
- swiper.allowClick = true;
- swiper.updateSize();
- swiper.swipeDirection = undefined;
- if (params.threshold > 0) data.allowThresholdMove = false;
- let preventDefault = true;
- if (targetEl.matches(data.focusableElements)) {
- preventDefault = false;
- if (targetEl.nodeName === 'SELECT') {
- data.isTouched = false;
- }
- }
- if (document.activeElement && document.activeElement.matches(data.focusableElements) && document.activeElement !== targetEl) {
- document.activeElement.blur();
- }
- const shouldPreventDefault = preventDefault && swiper.allowTouchMove && params.touchStartPreventDefault;
- if ((params.touchStartForcePreventDefault || shouldPreventDefault) && !targetEl.isContentEditable) {
- e.preventDefault();
- }
- if (params.freeMode && params.freeMode.enabled && swiper.freeMode && swiper.animating && !params.cssMode) {
- swiper.freeMode.onTouchStart();
- }
- swiper.emit('touchStart', e);
- }
|