UNPKG

pay-sdk-react

Version:

A cross-platform payment SDK for React, supporting Alipay, WeChat Pay, PayPal, Stripe, Payssion, and Airwallex, compatible with H5, PC, and App environments.

82 lines (81 loc) 2.49 kB
import { useEffect } from "react"; import { getScrollParent } from "../utils/get-scroll-parent"; import { supportsPassive } from "../utils/supports-passive"; import { useTouch } from "./use-touch"; let totalLockCount = 0; const BODY_LOCK_CLASS = "yfm-overflow-hidden"; function getScrollableElement(el) { let current = el === null || el === void 0 ? void 0 : el.parentElement; while (current) { if (current.clientHeight < current.scrollHeight) { return current; } current = current.parentElement; } return null; } export function useLockScroll(rootRef, shouldLock) { const touch = useTouch(); const onTouchMove = event => { touch.move(event); const direction = touch.deltaY.current > 0 ? "10" : "01"; const el = getScrollParent(event.target, rootRef.current); if (!el) return; // This has perf cost but we have to compatible with iOS 12 if (shouldLock === "strict") { const scrollableParent = getScrollableElement(event.target); if (scrollableParent === document.body || scrollableParent === document.documentElement) { event.preventDefault(); return; } } const { scrollHeight, offsetHeight, scrollTop } = el; const { height } = el.getBoundingClientRect(); let status = "11"; if (scrollTop === 0) { status = offsetHeight >= scrollHeight ? "00" : "01"; } else if (scrollHeight <= Math.round(height + scrollTop)) { status = "10"; } if (status !== "11" && touch.isVertical() && !(parseInt(status, 2) & parseInt(direction, 2))) { if (event.cancelable && supportsPassive) { event.preventDefault(); } } }; const lock = () => { document.addEventListener("touchstart", touch.start); document.addEventListener("touchmove", onTouchMove, supportsPassive ? { passive: false } : false); if (!totalLockCount) { document.body.classList.add(BODY_LOCK_CLASS); } totalLockCount++; }; const unlock = () => { if (totalLockCount) { document.removeEventListener("touchstart", touch.start); document.removeEventListener("touchmove", onTouchMove); totalLockCount--; if (!totalLockCount) { document.body.classList.remove(BODY_LOCK_CLASS); } } }; useEffect(() => { if (shouldLock) { lock(); return () => { unlock(); }; } // eslint-disable-next-line react-hooks/exhaustive-deps }, [shouldLock]); }