Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
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();
}
}
};
}() );
@webmaster-jhon

This comment has been minimized.

Copy link

commented Jan 27, 2015

Thanks for this file. I downloaded jquery.scrollLock.js but $.scrollLock(true) not working properly on my page. When i call this function scroll bar remains same i.e. still scroll able.

@RyKilleen

This comment has been minimized.

Copy link

commented Mar 5, 2015

Thank you, worked flawlessly. I needed to modify from scroll to hidden and feared having to tinker, but you had clearly prepared for that scenario. Very much appreciated.

@dsandstrom

This comment has been minimized.

Copy link

commented Nov 5, 2015

Thanks for this. Unfortunately the simple version does not work well on iOS. The page still scrolls underneath my overlay, overflow: hidden doesn't perform the same on Apple devices. I can't find documentation of this (go figure), but here is the fix I was using. However, when I use that CSS, the page scrolls to the top. Yet, the original version seems to work fine and locks the body scroll position in place.

@ahmednooor

This comment has been minimized.

Copy link

commented Mar 26, 2016

hi i am a novice and just know html and css a lil bit. i tried some solutions on the web but couldnt figure out how to tweak them according to my project and i hope this may work as it is not specified to some predefined classes. so could you plz tell the procedure to use it? like,

  1. where should i put the calling function?
  2. would i have to link to the jquery library in head too? or it will work on its own?
  3. if i have to put in my project specific class or id if it requires where should i put it?

for example i have a class .overlay which is hidden by default and when i click on on an anchor tag which is targeted to a div having the class .overlay and an id to get targeted and a modal opens i want to disable the body from scrolling when modal is opened.

sorry for asking an annoying question.

@jazcam

This comment has been minimized.

Copy link

commented Mar 29, 2016

Nice. Well done. Took a bit of doing, but between here and your demo on jsfiddle, I figured it out and have it working.

@xizon

This comment has been minimized.

Copy link

commented Apr 24, 2016

Thanks!

@sanketj14

This comment has been minimized.

Copy link

commented Oct 26, 2016

You sir, are my hero! you can't imagine just how much of my efforts are saved with this wonderful library. worked right off the bat! Thanks, keep up the good work!

@mrlaseptima

This comment has been minimized.

Copy link

commented Dec 22, 2016

hey men thank you

@m11z

This comment has been minimized.

Copy link

commented Feb 9, 2017

Thanks!

@tscrady

This comment has been minimized.

Copy link

commented Apr 19, 2017

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

@jessevdp

This comment has been minimized.

Copy link

commented Jun 13, 2017

👍

@mhshakouri

This comment has been minimized.

Copy link

commented Oct 23, 2017

this is a great tool I really recommend it
Thanks

@nitin00709

This comment has been minimized.

Copy link

commented Dec 19, 2017

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

This comment has been minimized.

Copy link

commented Feb 13, 2018

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

This comment has been minimized.

Copy link

commented Feb 21, 2018

Thanks brother , God bless you

@techlemur

This comment has been minimized.

Copy link

commented Mar 28, 2018

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

This comment has been minimized.

Copy link

commented Apr 3, 2018

Works perfectly 👍

@StrangerPings

This comment has been minimized.

Copy link

commented Apr 19, 2018

Thank you for this! 😃

@nilay255

This comment has been minimized.

Copy link

commented May 2, 2018

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

This comment has been minimized.

Copy link

commented Aug 7, 2018

Thanks alot for sharing

@BeholdPL

This comment has been minimized.

Copy link

commented Nov 20, 2018

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.