willmcpo / body-scroll-lock

Body scroll locking that just works with everything 😏
MIT License
4.06k stars 339 forks source link

When enabled, scrolls to top of document in iOS Safari on Version: 4.0.0-beta.0 #237

Open AlexandraKlein opened 3 years ago

AlexandraKlein commented 3 years ago

Version: 4.0.0-beta.0

Adds position: fixed to body on iOS, which causes the document to scroll to the top. This did not occur on previous version (v3.1.5).

Screen Shot 2021-10-25 at 8 58 49 AM
ipolikarpov commented 3 years ago

I can confirm this

ovenum commented 3 years ago

Same here on iOS 15.0.2. Workaround until this is fixed could be to offset the body position with window.scrollY and restore this when enabling body scrolling again.

// When disabling body scrolling
const storedScrollY = window.scrollY;

disableBodyScroll(el);
document.body.style.setProperty("top", `${window.scrollY * -1}px`);

// Enabling body scrolling
enableBodyScroll(el);

document.body.style.setProperty("top", "");
document.body.scrollTo(0, storedScrollY);

4.0.0-beta.0 is currently the version pulled from npm when no version is specified, so more people might come back with this issue.

GimpMaster commented 2 years ago

Confirming and following to see when there is a fix, for now I'll roll back.

jirbjirbjirb commented 2 years ago

Ran into exactly this same problem today! @basics09 thanks for the quick hack. Hope this gets resolved soon

joz3l commented 2 years ago
bsl_error

@willmcpo Not sure if cause of error, but the highlighted line 130 should probably be document.body.style.top = `-${scrollY + bottomBarHeight}px`; like the others. It seems related since when disabling scroll after bottom bar is hidden a blacked out region that size appears as if you had scrolled up and made the bottom bar appear. It's more easily observable on iOS 15 where the toolbar has moved to the bottom in case anyone is testing.

Edit: very certain this is the bug now. Here's a hack that doesn't result in the blacked out region, which I still get with @basics09's solution. Also oops, original sets style before calculating height, so I don't think bottom bar detection works with this approach though might still be preferable for some people.

// Disabling scroll works with temporary overwrite
const storedRequestAnimationFrame = window.requestAnimationFrame;

window.requestAnimationFrame = () => 42;
disableBodyScroll(element);
window.requestAnimationFrame = storedRequestAnimationFrame;

// Enabling scroll stays the same
enableBodyScroll(element);

If you're using React hooks use useLayoutEffect not useEffect otherwise lock doesn't activate initially due to something with render order. If you're building a modal with a height filling background, the bottom bar can still push your background around even if scroll is locked. To prevent this, make your background use { top: `${window.scrollY}px`, position: 'absolute' } instead of { top: 0, position: 'fixed' }. Hope this helps. 🙏

sinedoOo commented 2 years ago

Any update here?

rick-liruixin commented 1 year ago

They stopped the repairs. I had to do it myself, in the same way, with a new version of typeScript. And fix these problems for everyone to use. add react hooks、vue3 example

npm i body-scroll-lock-upgrade

repair log,Refer to the releases page.

rick-liruixin commented 1 year ago

今天遇到了同样的问题!@Basics09感谢您的快速破解。希望这很快得到解决

They stopped the repairs. I had to do it myself, in the same way, with a new version of typeScript. And fix these problems for everyone to use. add react hooks、vue3 example

npm i body-scroll-lock-upgrade

repair log,Refer to the releases page.