body-scroll-freezer
Dependency-free JS module to freeze body scroll when opening modal box.
Useful for modal, sliding-panel and lightbox interfaces.
<1kb minified.
A note on performance
Many other alternatives to this module listen to both mousewheel
and DOMMouseScroll
events in order to get some information from the DOM, which usually includes: Element.scrollTop
, event.deltaY
, Element.scrollHeight
or Element.clientHeight
. Check this StackOverflow answer as an example.
The problem is that most of those DOM operations (.scrollTop
and .scrollHeight
, for example) are expensive because they force layout/reflow. For more info on scrolling performance check out this article.
So, to avoid all that, body-scroll-freezer just assigns overflow: hidden;
and padding-right: [scrollWidth]px;
to the <body>
.
The overflow
avoids vertical move on the background when users are scrolling within the modal box. The padding-right
prevents horizontal jumps when hiding/showing the scrollbar.
Usage
var bodyScroll = require('body-scroll-freezer');
1. Init to calculate scroll bar width.
var scrollWidth = bodyScroll.init();
2. Turn scroll freeze ON when closing modal. Example:
document.querySelector('.modal-open').addEventListener('click', function() {
bodyScroll.freeze();
}, false);
3. Turn scroll freeze OFF when closing modal. Example:
document.querySelector('.modal-close').addEventListener('click', function() {
bodyScroll.unfreeze();
}, false);
Required CSS
.js-scrollbar-measure {
width: 100px;
height: 100px;
overflow: scroll;
position: absolute;
top: -9999px;
}