Sheet is too slow at iPhone
yunjin-kim opened this issue · comments
device: almost every iPhone
version: 17
browser: safari, chrome
react v18
react-dom v18
nextjs v12
react-modal-sheet v3.1.0
why preventScrollMobileSafari
this function execute too slow? only iPhone!
that function execute during 1.89sec
this image my iPhone web inspector.
in your library code
function preventScrollMobileSafari() {
let scrollable;
let lastY = 0;
const onTouchStart = (e) => {
scrollable = getScrollParent(e.target);
if (scrollable === document.documentElement && scrollable === document.body) {
return;
}
lastY = e.changedTouches[0].pageY;
};
const onTouchMove = (e) => {
if (scrollable === void 0) {
return;
}
if (scrollable === document.documentElement || scrollable === document.body) {
e.preventDefault();
return;
}
const y = e.changedTouches[0].pageY;
const scrollTop = scrollable.scrollTop;
const bottom = scrollable.scrollHeight - scrollable.clientHeight;
if (bottom === 0) {
return;
}
if (scrollTop <= 0 && y > lastY || scrollTop >= bottom && y < lastY) {
e.preventDefault();
}
lastY = y;
};
const onTouchEnd = (e) => {
const target = e.target;
if (willOpenKeyboard(target) && target !== document.activeElement) {
e.preventDefault();
target.style.transform = "translateY(-2000px)";
target.focus();
requestAnimationFrame(() => {
target.style.transform = "";
});
}
};
const onFocus = (e) => {
const target = e.target;
if (willOpenKeyboard(target)) {
target.style.transform = "translateY(-2000px)";
requestAnimationFrame(() => {
target.style.transform = "";
if (visualViewport) {
if (visualViewport.height < window.innerHeight) {
requestAnimationFrame(() => {
scrollIntoView(target);
});
} else {
visualViewport.addEventListener(
"resize",
() => {
scrollIntoView(target);
},
{ once: true }
);
}
}
});
}
};
const onWindowScroll = () => {
window.scrollTo(0, 0);
};
const scrollX = window.pageXOffset;
const scrollY = window.pageYOffset;
const restoreStyles = chain(
setStyle(
document.documentElement,
"paddingRight",
`${window.innerWidth - document.documentElement.clientWidth}px`
),
setStyle(document.documentElement, "overflow", "hidden"),
setStyle(document.body, "marginTop", `-${scrollY}px`)
);
window.scrollTo(0, 0);
const removeEvents = chain(
addEvent(document, "touchstart", onTouchStart, {
passive: false,
capture: true
}),
addEvent(document, "touchmove", onTouchMove, {
passive: false,
capture: true
}),
addEvent(document, "touchend", onTouchEnd, {
passive: false,
capture: true
}),
addEvent(document, "focus", onFocus, true),
addEvent(window, "scroll", onWindowScroll)
);
return () => {
restoreStyles();
removeEvents();
window.scrollTo(scrollX, scrollY);
};
}