Skip to content

Instantly share code, notes, and snippets.

@celian-rib
Forked from reecelucas/useScrollBlock.js
Last active May 24, 2024 08:54
Show Gist options
  • Save celian-rib/fcfb6ed3a96f86b4e7c3ea59df5c16a6 to your computer and use it in GitHub Desktop.
Save celian-rib/fcfb6ed3a96f86b4e7c3ea59df5c16a6 to your computer and use it in GitHub Desktop.
React hook to enable/disable page scroll (Typescript version)
import { useRef } from 'react';
const safeDocument: Document = document;
/**
* Usage:
* const [blockScroll, allowScroll] = useScrollBlock();
*/
export const useScrollBlock = (): [() => void, () => void] => {
const scrollBlocked = useRef(false);
const html = safeDocument.documentElement;
const { body } = safeDocument;
const blockScroll = (): void => {
if (!body || !body.style || scrollBlocked.current)
return;
if (document == undefined)
return;
const scrollBarWidth = window.innerWidth - html.clientWidth;
const bodyPaddingRight = parseInt(window.getComputedStyle(body).getPropertyValue('padding-right')) || 0;
/**
* 1. Fixes a bug in iOS and desktop Safari whereby setting
* `overflow: hidden` on the html/body does not prevent scrolling.
* 2. Fixes a bug in desktop Safari where `overflowY` does not prevent
* scroll if an `overflow-x` style is also applied to the body.
*/
html.style.position = 'relative'; /* [1] */
html.style.overflow = 'hidden'; /* [2] */
body.style.position = 'relative'; /* [1] */
body.style.overflow = 'hidden'; /* [2] */
body.style.paddingRight = `${bodyPaddingRight + scrollBarWidth}px`;
scrollBlocked.current = true;
};
const allowScroll = (): void => {
if (!body || !body.style || !scrollBlocked.current) return;
html.style.position = '';
html.style.overflow = '';
body.style.position = '';
body.style.overflow = '';
body.style.paddingRight = '';
scrollBlocked.current = false;
};
return [blockScroll, allowScroll];
};
@dharmatriyasa
Copy link

cool man, it work. thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment