Skip to content

Instantly share code, notes, and snippets.

@edaston
Forked from reecelucas/useScrollBlock.js
Created April 22, 2022 04:37
Show Gist options
  • Select an option

  • Save edaston/097a55ae0659588063a8bf9fc12e11a3 to your computer and use it in GitHub Desktop.

Select an option

Save edaston/097a55ae0659588063a8bf9fc12e11a3 to your computer and use it in GitHub Desktop.

Revisions

  1. @reecelucas reecelucas revised this gist Apr 23, 2020. 1 changed file with 4 additions and 6 deletions.
    10 changes: 4 additions & 6 deletions useScrollBlock.js
    Original file line number Diff line number Diff line change
    @@ -14,11 +14,9 @@ export default () => {
    const blockScroll = () => {
    if (!body || !body.style || scrollBlocked.current) return;

    /**
    * `body.clientWidth` returns the inner width of the body, including
    * any padding but not vertical scrollbars (if there are any).
    */
    const scrollBarWidth = window.innerWidth - body.clientWidth;
    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
    @@ -30,7 +28,7 @@ export default () => {
    html.style.overflow = 'hidden'; /* [2] */
    body.style.position = 'relative'; /* [1] */
    body.style.overflow = 'hidden'; /* [2] */
    body.style.paddingRight = `${scrollBarWidth}px`;
    body.style.paddingRight = `${bodyPaddingRight + scrollBarWidth}px`;

    scrollBlocked.current = true;
    };
  2. @reecelucas reecelucas created this gist Apr 2, 2019.
    51 changes: 51 additions & 0 deletions useScrollBlock.js
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,51 @@
    import { useRef } from 'react';

    const safeDocument = typeof document !== 'undefined' ? document : {};

    /**
    * Usage:
    * const [blockScroll, allowScroll] = useScrollBlock();
    */
    export default () => {
    const scrollBlocked = useRef();
    const html = safeDocument.documentElement;
    const { body } = safeDocument;

    const blockScroll = () => {
    if (!body || !body.style || scrollBlocked.current) return;

    /**
    * `body.clientWidth` returns the inner width of the body, including
    * any padding but not vertical scrollbars (if there are any).
    */
    const scrollBarWidth = window.innerWidth - body.clientWidth;

    /**
    * 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 = `${scrollBarWidth}px`;

    scrollBlocked.current = true;
    };

    const allowScroll = () => {
    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];
    };