Skip to content

Instantly share code, notes, and snippets.

@barneycarroll
Last active March 20, 2026 10:00
Show Gist options
  • Select an option

  • Save barneycarroll/6550066 to your computer and use it in GitHub Desktop.

Select an option

Save barneycarroll/6550066 to your computer and use it in GitHub Desktop.
Lock and unlock a page's scroll position.

jquery.scrollLock.js

Useful for when a blocking user experience is needed (in my case, didn't want people unwittingly loosing their place by scrolling while a modal required their attention): $.scrollLock() locks the body in place, preventing scroll until it is unlocked.

// Locks the page if it's currently unlocked
$.scrollLock();

// ...or vice versa
$.scrollLock();

// Locks the page
$.scrollLock( true );

// Unlocks the page
$.scrollLock( false );
$.scrollLock = ( function scrollLockClosure() {
'use strict';
var $html = $( 'html' ),
// State: unlocked by default
locked = false,
// State: scroll to revert to
prevScroll = {
scrollLeft : $( window ).scrollLeft(),
scrollTop : $( window ).scrollTop()
},
// State: styles to revert to
prevStyles = {},
lockStyles = {
'overflow-y' : 'scroll',
'position' : 'fixed',
'width' : '100%'
};
// Instantiate cache in case someone tries to unlock before locking
saveStyles();
// Save context's inline styles in cache
function saveStyles() {
var styleAttr = $html.attr( 'style' ),
styleStrs = [],
styleHash = {};
if( !styleAttr ){
return;
}
styleStrs = styleAttr.split( /;\s/ );
$.each( styleStrs, function serializeStyleProp( styleString ){
if( !styleString ) {
return;
}
var keyValue = styleString.split( /\s:\s/ );
if( keyValue.length < 2 ) {
return;
}
styleHash[ keyValue[ 0 ] ] = keyValue[ 1 ];
} );
$.extend( prevStyles, styleHash );
}
function lock() {
var appliedLock = {};
// Duplicate execution will break DOM statefulness
if( locked ) {
return;
}
// Save scroll state...
prevScroll = {
scrollLeft : $( window ).scrollLeft(),
scrollTop : $( window ).scrollTop()
};
// ...and styles
saveStyles();
// Compose our applied CSS
$.extend( appliedLock, lockStyles, {
// And apply scroll state as styles
'left' : - prevScroll.scrollLeft + 'px',
'top' : - prevScroll.scrollTop + 'px'
} );
// Then lock styles...
$html.css( appliedLock );
// ...and scroll state
$( window )
.scrollLeft( 0 )
.scrollTop( 0 );
locked = true;
}
function unlock() {
// Duplicate execution will break DOM statefulness
if( !locked ) {
return;
}
// Revert styles
$html.attr( 'style', $( '<x>' ).css( prevStyles ).attr( 'style' ) || '' );
// Revert scroll values
$( window )
.scrollLeft( prevScroll.scrollLeft )
.scrollTop( prevScroll.scrollTop );
locked = false;
}
return function scrollLock( on ) {
// If an argument is passed, lock or unlock depending on truthiness
if( arguments.length ) {
if( on ) {
lock();
}
else {
unlock();
}
}
// Otherwise, toggle
else {
if( locked ){
unlock();
}
else {
lock();
}
}
};
}() );
$.scrollLock = ( function scrollLockSimple(){
var locked = false;
var $body;
var previous;
function lock(){
if( !$body ){
$body = $( 'body' );
}
previous = $body.css( 'overflow' );
$body.css( 'overflow', 'hidden' );
locked = true;
}
function unlock(){
$body.css( 'overflow', previous );
locked = false;
}
return function scrollLock( on ) {
// If an argument is passed, lock or unlock depending on truthiness
if( arguments.length ) {
if( on ) {
lock();
}
else {
unlock();
}
}
// Otherwise, toggle
else {
if( locked ){
unlock();
}
else {
lock();
}
}
};
}() );
@tscrady

tscrady commented Apr 19, 2017

Copy link
Copy Markdown

Thank you very much, works on ios10, Firefox 51.0.1, Chrome Version 56.0.2924.87

@jessevdp

Copy link
Copy Markdown

๐Ÿ‘

@mhshakouri

Copy link
Copy Markdown

this is a great tool I really recommend it
Thanks

@nitin00709

Copy link
Copy Markdown

Thanks a lot for this wonderful library. It worked flawlessly. I had been trying for so long to hide scrolling on body while a pop-up window appears on ios, you have saved a lot of my time. Very much appreciated. I really recommend it. For those who are dealing with such issue I really recommend you to use this one it works on ios devices too.

@Dylan-Harrington

Dylan-Harrington commented Feb 13, 2018

Copy link
Copy Markdown

This is incredible. Multiple days of searching for an answer and trying a thousand different things finally concluded thanks to this little library. I hope everyone grinding their teeth over this issue finds it soon. Thank you SO much!

@leonardoervilha

Copy link
Copy Markdown

Thanks brother , God bless you

@techlemur

Copy link
Copy Markdown

Thank you! Works perfectly except for an occasional error with "styleAttr.split". Easily fixed by changing line 33 to the following:
try { styleStrs = styleAttr.split(/;\s/); } catch (err) { return; }

@hiddebijnerds

Copy link
Copy Markdown

Works perfectly ๐Ÿ‘

@StrangerPings

Copy link
Copy Markdown

Thank you for this! ๐Ÿ˜ƒ

@nilay255

nilay255 commented May 2, 2018

Copy link
Copy Markdown

How do I check if the scrollLock is active or not for jquery.scrollLock.js? Like how do I check the locked status is true or false. @barneycarroll

@rajakhoury

Copy link
Copy Markdown

Thanks alot for sharing

@BeholdPL

BeholdPL commented Nov 20, 2018

Copy link
Copy Markdown

Works great! But when scroll is locked, then every position: fixed elements on site are disappear. Is there possibility to avoid that?

@locopump

Copy link
Copy Markdown

Do you have any example of use of this code ??

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