@cainiaofe/cn-ui-m
Version:
71 lines (70 loc) • 2.53 kB
JavaScript
import { useTouch } from './use-touch';
import { useEffect } from 'react';
import { getScrollParent } from './get-scroll-parent';
import { supportsPassive } from './supports-passive';
var totalLockCount = 0;
function getScrollableElement(el) {
var current = el === null || el === void 0 ? void 0 : el.parentElement;
while (current) {
if (current.clientHeight < current.scrollHeight) {
return current;
}
current = current.parentElement;
}
return null;
}
// 移植自vant:https://github.com/youzan/vant/blob/HEAD/src/composables/use-lock-scroll.ts
export function useLockScroll(rootRef, shouldLock) {
var touch = useTouch();
var onTouchMove = function (event) {
touch.move(event);
var direction = touch.deltaY.current > 0 ? '10' : '01';
var el = getScrollParent(event.target, rootRef.current);
if (!el)
return;
// This has perf cost but we have to compatible with iOS 12
if (shouldLock === 'strict') {
var scrollableParent = getScrollableElement(event.target);
if (scrollableParent === document.body ||
scrollableParent === document.documentElement) {
event.preventDefault();
return;
}
}
var scrollHeight = el.scrollHeight, offsetHeight = el.offsetHeight, scrollTop = el.scrollTop;
var status = '11';
if (scrollTop === 0) {
status = offsetHeight >= scrollHeight ? '00' : '01';
}
else if (scrollTop + offsetHeight >= scrollHeight) {
status = '10';
}
if (status !== '11' &&
touch.isVertical() &&
!(parseInt(status, 2) & parseInt(direction, 2))) {
if (event.cancelable) {
event.preventDefault();
}
}
};
var lock = function () {
document.addEventListener('touchstart', touch.start);
document.addEventListener('touchmove', onTouchMove, supportsPassive ? { passive: false } : false);
totalLockCount++;
};
var unlock = function () {
if (totalLockCount) {
document.removeEventListener('touchstart', touch.start);
document.removeEventListener('touchmove', onTouchMove);
totalLockCount--;
}
};
useEffect(function () {
if (shouldLock) {
lock();
return function () {
unlock();
};
}
}, [shouldLock]);
}