22

How can I lock scrolling of a webpage temporarily when a dialog box is displayed ? I have a dialog box within which I want to enable scrolling after deactivating scrolling from the overlayed webpage.

Is there a js command to temporarily disable scrolling ?

Rajat Gupta
  • 25,853
  • 63
  • 179
  • 294

4 Answers4

27

EDIT Try this:

On dialog open (remove scrollbar and prevent user from scrolling):

  $('body').css({'overflow':'hidden'});
  $(document).bind('scroll',function () { 
       window.scrollTo(0,0); 
  });

On Dialog Close(allow user to scroll again):

 $(document).unbind('scroll'); 
  $('body').css({'overflow':'visible'});
Limpan
  • 662
  • 1
  • 5
  • 6
  • 1
    THIS. Thank you so much. I was looking for hours to find something like this. It's the only really working solution on all browsers I tested so far. – Hillcow Jul 11 '18 at 10:55
  • @Limpan just out of curiosity why do you need the eventListener as well? in major browsers setting overflow to hidden is enough – halafi Jun 29 '20 at 08:52
  • BUG WARNING: Every solution I have found online like this causes a problem if you use Google ReCapcha within a FORM element in the popup. When the Google ReCapcha triggers its own popup within a form element in your popup it may be 1000s of pixels "above" where it should be, and the user can not scroll to it. Just watched this destroy the conversion rate on several landing pages that had "popup forms" with "locked" scroll bars... because people could not complete the ReCapcha – Christian Žagarskas Mar 08 '23 at 19:00
12

You could set a container element or maybe even the body to overflow: hidden with a width and height of the browser window. This way any overflowing content will fall off the page and scroll bars are never displayed. This can be set in a css statement like body.dialog-open { overflow: hidden; }. You can then add and remove the .dialog-open classname when the dialog opens and closes.

The width and height might not be required if setting this on the body, but I'd have to check browser compatibility on that one. Might get some unexpected results there.

edit: If you want scrolling inside your dialog you can set overflow: auto there, with a height set on that element.

Older browsers (most notably IE) might show a horizontal scrollbar as well, you might have to set overflow-x: hidden if that is the case.

Also see: CSS div element - how to show horizontal scroll bars only? for more information on scrollbars.

Community
  • 1
  • 1
Kamiel Wanrooij
  • 12,164
  • 6
  • 37
  • 43
  • Also beware that Opera has an old bug causing it to ignore overflow:hidden when using the scroll wheel. (No easy workaround either) – Stein G. Strindhaug Jun 20 '11 at 12:47
  • Initially the webpage is scrollable, but only for the time dialog isdisabled, I want to temporarily disable scrolling, so I guess your sol. wont work – Rajat Gupta Jun 20 '11 at 12:55
  • 1
    It will. You can just add a classname to the body when the dialog opens, and remove it when it closes. Will update the post to add this. – Kamiel Wanrooij Jun 20 '11 at 13:31
  • he asked for JavaScript – quemeful Jan 18 '19 at 12:11
  • 1
    This removes the scrollbar from the viewport and messes with the `` element. – ihodonald Jan 14 '20 at 02:26
  • BUG WARNING: Every solution I have found online like this causes a problem if you use Google ReCapcha within a FORM element in the popup. When the Google ReCapcha triggers its own popup within a form element in your popup it may be 1000s of pixels "above" where it should be, and the user can not scroll to it. Just watched this destroy the conversion rate on several landing pages that had "popup forms" with "locked" scroll bars... because people could not complete the ReCapcha – Christian Žagarskas Mar 08 '23 at 19:00
5

Here is vanilla JS version:

document.getElementsByTagName('body')[0].style.overflow = 'hidden';
...
document.getElementsByTagName('body')[0].style.overflow = 'visible' // the default for the css property
halafi
  • 1,064
  • 2
  • 16
  • 26
1

It's a copy of my answer that I posted here: https://stackoverflow.com/a/63221105/4336168

I use these two functions for this:

function enableBodyScroll() {
  if (document.readyState === 'complete') {
    document.body.style.position = '';
    document.body.style.overflowY = '';

    if (document.body.style.marginTop) {
      const scrollTop = -parseInt(document.body.style.marginTop, 10);
      document.body.style.marginTop = '';
      window.scrollTo(window.pageXOffset, scrollTop);
    }
  } else {
    window.addEventListener('load', enableBodyScroll);
  }
}

function disableBodyScroll({ savePosition = false } = {}) {
  if (document.readyState === 'complete') {
    if (document.body.scrollHeight > window.innerHeight) {
      if (savePosition) document.body.style.marginTop = `-${window.pageYOffset}px`;
      document.body.style.position = 'fixed';
      document.body.style.overflowY = 'scroll';
    }
  } else {
    window.addEventListener('load', () => disableBodyScroll({ savePosition }));
  }
}

How it works:

  1. When you want to disable the scroll with saving the current position, you run disableBodyScroll({ savePosition: true }).

  2. The function check whether the page loaded or not (because user may trigger dialog opening during the loading).

  3. If the page is loaded, it saves current scroll position by setting margin-top on body, then it sets position: fixed; overflow-y: scroll on it to remove scrollbar.

  4. If the page isn't loaded, it adds event listener to run (3.) when the page loads.

For enabling scroll everything is the same, but the function remove styles instead of setting them.

Source of the code, so they can be used like this:

npm install --save @funboxteam/diamonds
import { enableBodyScroll, disableBodyScroll } from '@funboxteam/diamonds';
Igor Adamenko
  • 861
  • 1
  • 8
  • 20
  • After running the "enableBodyScroll()" function it scroll the body from top, how can i prevent it. I want to enable scroll from the exact location where the scroll was locked. – Anuj Thapa Sep 11 '22 at 08:21
  • @AnujThapa, if you passed `savePosition: true` to `disableBodyScroll`, then the scrolled position will be saved, and `enableBodyScroll` will respect this position. – Igor Adamenko Nov 20 '22 at 13:58