Gathering detailed insights and metrics for body-scroll-lock-upgrade
Gathering detailed insights and metrics for body-scroll-lock-upgrade
Gathering detailed insights and metrics for body-scroll-lock-upgrade
Gathering detailed insights and metrics for body-scroll-lock-upgrade
quiaqui
Enables body scroll locking (for iOS Mobile and Tablet, Android, desktop Safari/Chrome/Firefox) without breaking scrolling of a target element (eg. modal/lightbox/flyouts/nav-menus)
body-scroll-lock-enhanced
Enables body scroll locking (for iOS Mobile and Tablet, Android, desktop Safari/Chrome/Firefox) without breaking scrolling of a target element (eg. modal/lightbox/flyouts/nav-menus)
Body scroll locking that just works with everything 😏
npm install body-scroll-lock-upgrade
Typescript
Module System
Node Version
NPM Version
TypeScript (92.32%)
JavaScript (7.68%)
Total Downloads
0
Last Day
0
Last Week
0
Last Month
0
Last Year
0
MIT License
132 Stars
23 Commits
3 Forks
4 Watchers
5 Branches
1 Contributors
Updated on May 10, 2025
Latest Version
1.1.0
Package Id
body-scroll-lock-upgrade@1.1.0
Unpacked Size
85.39 kB
Size
12.56 kB
File Count
11
NPM Version
6.14.15
Node Version
14.18.2
Published on
Dec 01, 2023
Cumulative downloads
Total Downloads
Last Day
0%
NaN
Compared to previous day
Last Week
0%
NaN
Compared to previous week
Last Month
0%
NaN
Compared to previous month
Last Year
0%
NaN
Compared to previous year
5
body-scroll-lock upgrade version, repair body-scroll-lock v4.0.0-beta.0 bug。
They stopped maintenance. I had to work it out myself, using the same approach, with a new version of typeScript. And fix the original problem, available for everyone to use.
Refer to the releases page.
If you think it works for you, please give me a star ⭐️ to encourage me
go to github ⭐️⭐️⭐️⭐️⭐️
Enables body scroll locking (for iOS Mobile and Tablet, Android, desktop Safari/Chrome/Firefox) without breaking scrolling of a target element (eg. modal/lightbox/flyouts/nav-menus).
Features:
-webkit-overflow-scrolling: touch
still worksAren't the alternative approaches sufficient?
document.body.ontouchmove = (e) => { e.preventDefault(); return false; };
locks the
body scroll, but ALSO locks the scroll of a target element (eg. modal).overflow: hidden
on the body or html elements doesn't work for all browsersposition: fixed
approach causes the body scroll to reset$ yarn add body-scroll-lock-upgrade
or
$ npm install body-scroll-lock-upgrade
You can also load via a <script src="lib/bodyScrollLock.js"></script>
tag (refer to the lib folder).
1// 1. Import the functions 2const bodyScrollLock = require('body-scroll-lock-upgrade'); 3const disableBodyScroll = bodyScrollLock.disableBodyScroll; 4const enableBodyScroll = bodyScrollLock.enableBodyScroll; 5 6// 2. Get a target element that you want to persist scrolling for (such as a modal/lightbox/flyout/nav). 7// Specifically, the target element is the one we would like to allow scroll on (NOT a parent of that element). 8// This is also the element to apply the CSS '-webkit-overflow-scrolling: touch;' if desired. 9const targetElement = document.querySelector('#someElementId'); 10 11// 3. ...in some event handler after showing the target element...disable body scroll 12disableBodyScroll(targetElement); 13 14// 4. ...in some event handler after hiding the target element... 15enableBodyScroll(targetElement);
1// 1. Import the functions 2import { 3 disableBodyScroll, 4 enableBodyScroll, 5 clearAllBodyScrollLocks, 6} from 'body-scroll-lock-upgrade'; 7 8class SomeComponent extends React.Component { 9 targetElement = null; 10 11 componentDidMount() { 12 // 2. Get a target element that you want to persist scrolling for (such as a modal/lightbox/flyout/nav). 13 // Specifically, the target element is the one we would like to allow scroll on (NOT a parent of that element). 14 // This is also the element to apply the CSS '-webkit-overflow-scrolling: touch;' if desired. 15 this.targetElement = document.querySelector('#targetElementId'); 16 } 17 18 showTargetElement = () => { 19 // ... some logic to show target element 20 21 // 3. Disable body scroll 22 disableBodyScroll(this.targetElement); 23 }; 24 25 hideTargetElement = () => { 26 // ... some logic to hide target element 27 28 // 4. Re-enable body scroll 29 enableBodyScroll(this.targetElement); 30 }; 31 32 componentWillUnmount() { 33 // 5. Useful if we have called disableBodyScroll for multiple target elements, 34 // and we just want a kill-switch to undo all that. 35 // OR useful for if the `hideTargetElement()` function got circumvented eg. visitor 36 // clicks a link which takes him/her to a different page within the app. 37 clearAllBodyScrollLocks(); 38 } 39 40 render() { 41 return <div>some JSX to go here</div>; 42 } 43}
1// 1. Import the functions 2import { 3 disableBodyScroll, 4 enableBodyScroll, 5 clearAllBodyScrollLocks, 6} from 'body-scroll-lock-upgrade'; 7 8class SomeComponent extends React.Component { 9 // 2. Initialise your ref and targetElement here 10 targetRef = React.createRef(); 11 targetElement = null; 12 13 componentDidMount() { 14 // 3. Get a target element that you want to persist scrolling for (such as a modal/lightbox/flyout/nav). 15 // Specifically, the target element is the one we would like to allow scroll on (NOT a parent of that element). 16 // This is also the element to apply the CSS '-webkit-overflow-scrolling: touch;' if desired. 17 this.targetElement = this.targetRef.current; 18 } 19 20 showTargetElement = () => { 21 // ... some logic to show target element 22 23 // 4. Disable body scroll 24 disableBodyScroll(this.targetElement); 25 }; 26 27 hideTargetElement = () => { 28 // ... some logic to hide target element 29 30 // 5. Re-enable body scroll 31 enableBodyScroll(this.targetElement); 32 }; 33 34 componentWillUnmount() { 35 // 5. Useful if we have called disableBodyScroll for multiple target elements, 36 // and we just want a kill-switch to undo all that. 37 // OR useful for if the `hideTargetElement()` function got circumvented eg. visitor 38 // clicks a link which takes him/her to a different page within the app. 39 clearAllBodyScrollLocks(); 40 } 41 42 render() { 43 return ( 44 // 6. Pass your ref with the reference to the targetElement to SomeOtherComponent 45 <SomeOtherComponent ref={this.targetRef}> 46 some JSX to go here 47 </SomeOtherComponent> 48 ); 49 } 50} 51 52// 7. SomeOtherComponent needs to be a Class component to receive the ref (unless Hooks - https://reactjs.org/docs/hooks-faq.html#can-i-make-a-ref-to-a-function-component - are used). 53class SomeOtherComponent extends React.Component { 54 componentDidMount() { 55 // Your logic on mount goes here 56 } 57 58 // 8. BSL will be applied to div below in SomeOtherComponent and persist scrolling for the container 59 render() { 60 return <div>some JSX to go here</div>; 61 } 62}
1import { Component, ElementRef, OnDestroy, ViewChild } from '@angular/core'; 2 3// 1. Import the functions 4import { 5 disableBodyScroll, 6 enableBodyScroll, 7 clearAllBodyScrollLocks, 8} from 'body-scroll-lock-upgrade'; 9 10@Component({ 11 selector: 'app-scroll-block', 12 templateUrl: './scroll-block.component.html', 13 styleUrls: ['./scroll-block.component.css'], 14}) 15export class SomeComponent implements OnDestroy { 16 // 2. Get a target element that you want to persist scrolling for (such as a modal/lightbox/flyout/nav). 17 // Specifically, the target element is the one we would like to allow scroll on (NOT a parent of that element). 18 // This is also the element to apply the CSS '-webkit-overflow-scrolling: touch;' if desired. 19 @ViewChild('scrollTarget') scrollTarget: ElementRef; 20 21 showTargetElement() { 22 // ... some logic to show target element 23 24 // 3. Disable body scroll 25 disableBodyScroll(this.scrollTarget.nativeElement); 26 } 27 28 hideTargetElement() { 29 // ... some logic to hide target element 30 31 // 4. Re-enable body scroll 32 enableBodyScroll(this.scrollTarget.nativeElement); 33 } 34 35 ngOnDestroy() { 36 // 5. Useful if we have called disableBodyScroll for multiple target elements, 37 // and we just want a kill-switch to undo all that. 38 // OR useful for if the `hideTargetElement()` function got circumvented eg. visitor 39 // clicks a link which takes him/her to a different page within the app. 40 clearAllBodyScrollLocks(); 41 } 42}
Then in the javascript:
1 2<script type="module"> 3 4 import { 5 clearAllBodyScrollLocks, 6 disableBodyScroll, 7 enableBodyScroll, 8 } from "https://cdn.jsdelivr.net/gh/rick-liruixin/body-scroll-lock-upgrade@v1.1.0/lib/index.esm.js"; 9 10 // 1. Get a target element that you want to persist scrolling for (such as a modal/lightbox/flyout/nav). 11 // Specifically, the target element is the one we would like to allow scroll on (NOT a parent of that element). 12 // This is also the element to apply the CSS '-webkit-overflow-scrolling: touch;' if desired. 13 const targetElement = document.querySelector("#someElementId"); 14 15 // 2. ...in some event handler after showing the target element...disable body scroll 16 disableBodyScroll(targetElement); 17 18 // 3. ...in some event handler after hiding the target element... 19 enableBodyScroll(targetElement); 20 21 // 4. Useful if we have called disableBodyScroll for multiple target elements, 22 // and we just want a kill-switch to undo all that. 23 clearAllBodyScrollLocks(); 24 25</script> 26 27// UMD 28<script src="https://cdn.jsdelivr.net/gh/rick-liruixin/body-scroll-lock-upgrade@v1.1.0/lib/index.umd.js"></script> 29<script> 30 const open = () => { 31 document.querySelector(".dialog").style.display = "block"; 32 document.querySelector(".mask").style.display = "block"; 33 const targetElement = document.querySelector(".dialog"); 34 bodyScrollLockUpgrade.disableBodyScroll(targetElement); 35 }; 36 const close = () => { 37 document.querySelector(".dialog").style.display = "none"; 38 document.querySelector(".mask").style.display = "none"; 39 const targetElement = document.querySelector(".dialog"); 40 bodyScrollLockUpgrade.enableBodyScroll(targetElement); 41 }; 42 document.getElementById("open").addEventListener("click", open); 43 document.getElementById("close").addEventListener("click", close); 44</script>
Check out the demo, powered by Vercel.
Function | Arguments | Return | Description |
---|---|---|---|
disableBodyScroll | targetElement: HTMLElement options: BodyScrollOptions | void | Disables body scroll while enabling scroll on target element |
enableBodyScroll | targetElement: HTMLElement | void | Enables body scroll and removing listeners on target element |
clearAllBodyScrollLocks | null | void | Clears all scroll locks |
optional, default: false
If the overflow property of the body is set to hidden, the body widens by the width of the scrollbar. This produces an
unpleasant flickering effect, especially on websites with centered content. If the reserveScrollBarGap
option is set,
this gap is filled by a padding-right
on the body element. If disableBodyScroll
is called for the last target element,
or clearAllBodyScrollLocks
is called, the padding-right
is automatically reset to the previous value.
1import { disableBodyScroll } from 'body-scroll-lock-upgrade'; 2import type { BodyScrollOptions } from 'body-scroll-lock-upgrade'; 3 4const options: BodyScrollOptions = { 5 reserveScrollBarGap: true, 6}; 7 8disableBodyScroll(targetElement, options);
optional, default: undefined
To disable scrolling on iOS, disableBodyScroll
prevents touchmove
events.
However, there are cases where you have called disableBodyScroll
on an
element, but its children still require touchmove
events to function.
See below for 2 use cases:
1disableBodyScroll(container, { 2 allowTouchMove: (el) => el.tagName === 'TEXTAREA', 3});
Javascript:
1disableBodyScroll(container, { 2 allowTouchMove: (el) => { 3 while (el && el !== document.body) { 4 if (el.getAttribute('body-scroll-lock-ignore') !== null) { 5 return true; 6 } 7 8 el = el.parentElement; 9 } 10 }, 11});
Html:
1<div id="container"> 2 <div id="scrolling-map" body-scroll-lock-ignore>...</div> 3</div>
https://medium.com/jsdownunder/locking-body-scroll-for-all-devices-22def9615177 https://stackoverflow.com/questions/41594997/ios-10-safari-prevent-scrolling-behind-a-fixed-overlay-and-maintain-scroll-posi
No vulnerabilities found.
No security vulnerabilities found.