mirror of
https://github.com/streamich/react-use.git
synced 2026-01-18 14:06:52 +00:00
feat: add support for body lock on iOS
This commit is contained in:
commit
d7784084fe
@ -15,15 +15,33 @@ export function getClosestBody(el: Element | HTMLElement | HTMLIFrameElement | n
|
||||
return getClosestBody((el as HTMLElement).offsetParent!);
|
||||
}
|
||||
|
||||
function preventDefault(rawEvent: TouchEvent): boolean {
|
||||
const e = rawEvent || window.event;
|
||||
// Do not prevent if the event has more than one touch (usually meaning this is a multi touch gesture like pinch to zoom).
|
||||
if (e.touches.length > 1) return true;
|
||||
|
||||
if (e.preventDefault) e.preventDefault();
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
export interface BodyInfoItem {
|
||||
counter: number;
|
||||
initialOverflow: CSSStyleDeclaration['overflow'];
|
||||
}
|
||||
|
||||
const isIosDevice =
|
||||
typeof window !== 'undefined' &&
|
||||
window.navigator &&
|
||||
window.navigator.platform &&
|
||||
/iP(ad|hone|od)/.test(window.navigator.platform);
|
||||
|
||||
const bodies: Map<HTMLElement, BodyInfoItem> = new Map();
|
||||
|
||||
const doc: Document | undefined = typeof document === 'object' ? document : undefined;
|
||||
|
||||
let documentListenerAdded = false;
|
||||
|
||||
export default !doc
|
||||
? function useLockBodyMock(_locked: boolean = true, _elementRef?: RefObject<HTMLElement>) {}
|
||||
: function useLockBody(locked: boolean = true, elementRef?: RefObject<HTMLElement>) {
|
||||
@ -40,7 +58,15 @@ export default !doc
|
||||
if (locked) {
|
||||
if (!bodyInfo) {
|
||||
bodies.set(body, { counter: 1, initialOverflow: body.style.overflow });
|
||||
body.style.overflow = 'hidden';
|
||||
if (isIosDevice) {
|
||||
if (!documentListenerAdded) {
|
||||
document.addEventListener('touchmove', preventDefault, { passive: false });
|
||||
|
||||
documentListenerAdded = true;
|
||||
}
|
||||
} else {
|
||||
body.style.overflow = 'hidden';
|
||||
}
|
||||
} else {
|
||||
bodies.set(body, { counter: bodyInfo.counter + 1, initialOverflow: bodyInfo.initialOverflow });
|
||||
}
|
||||
@ -48,7 +74,16 @@ export default !doc
|
||||
if (bodyInfo) {
|
||||
if (bodyInfo.counter === 1) {
|
||||
bodies.delete(body);
|
||||
body.style.overflow = bodyInfo.initialOverflow;
|
||||
if (isIosDevice) {
|
||||
body.ontouchmove = null;
|
||||
|
||||
if (documentListenerAdded) {
|
||||
document.removeEventListener('touchmove', preventDefault);
|
||||
documentListenerAdded = false;
|
||||
}
|
||||
} else {
|
||||
body.style.overflow = bodyInfo.initialOverflow;
|
||||
}
|
||||
} else {
|
||||
bodies.set(body, { counter: bodyInfo.counter - 1, initialOverflow: bodyInfo.initialOverflow });
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user