How to disable scroll without hiding it?
If the page under the overlayer can be "fixed" at the top, when you open the overlay you can set
body { position: fixed; overflow-y:scroll }
you should still see the right scrollbar but the content is not scrollable. When you close the overlay just revert these properties with
body { position: static; overflow-y:auto }
I just proposed this way only because you wouldn't need to change any scroll event
Update
You could also do a slight improvement: if you get the document.documentElement.scrollTop
property via javascript just before the layer opening, you could dynamically assign that value as top
property of the body element: with this approach the page will stand in its place, no matter if you're on top or if you have already scrolled.
Css
.noscroll { position: fixed; overflow-y:scroll }
JS
$('body').css('top', -(document.documentElement.scrollTop) + 'px')
.addClass('noscroll');
Disable scrolling but keep scrollbar CSS
Instead of changing the css
, which will remove the scrollbar
, and as you said change the layout of the page, try calling a jquery function
instead.
// call your pop up and inside that function add below
$('body').on('scroll mousewheel touchmove', function(e) {
e.preventDefault();
e.stopPropagation();
return false;
});
then when you close the modal, call the same function but replace on
with off
Disable scroll but without hiding the scroll bar for React JS?
You could just add an event to the onscroll, and then keep a track of the current scrollTop, scrollLeft (if you need to handle horizontal too), and then when you don't want scroll just reset the scroll to these stored values.
eg. If you run the snippet below when the large checkbox is checked, scrolling is disabled.
const div = document.querySelector('div');
const cb = document.querySelector('input');
let lastY = 0;
div.innerText = new Array(3000).fill().map(m => 'hello ').join(' ');
div.addEventListener('scroll', (e) => {
if (cb.checked) {
e.target.scrollTop = lastY;
} else lastY = e.target.scrollTop;
});
cb.addEventListener('click', () => {
console.log('click');
});
div {
height: 150px;
overflow: auto;
}
input {
position: fixed;
top: 50px;
left: 50px;
transform: scale(4);
}
<div>
</div>
<input type="checkbox"/>
Disable body scroll but don't hide scrollbar
One approach that's both very simple and effective is to not have the main content in the body itself, but a wrapper that's a sibling with the overlay. With this approach you can toggle the overlay whenever necessary without affecting the scroll of the content element.
var e = document.getElementById('overlay');document.body.onclick = function() { e.style.display = (!e.style.display || e.style.display === 'block') ? 'none' : 'block';};
html,body,#content { height: 100%; margin: 0;}#content { overflow: auto;}#high { height: 800px;}#overlay { position: absolute; height: 100%; width: 100%; background: rgba(0, 0, 0, 0.5);}
<div id="overlay"></div><div id="content"> Long content resides in this container <div id="high"></div> And the long content ends here</div>
Prevent body scrolling but allow overlay scrolling
Theory
Looking at current implementation of the pinterest site (it might change in the future), when you open the overlay a noscroll
class is applied to the body
element and overflow: hidden
is set, thus body
is no longer scrollable.
The overlay (created on-the-fly or already inside the page and made visible via display: block
, it makes no difference) has position : fixed
and overflow-y: scroll
, with top
, left
, right
and bottom
properties set to 0
: this style makes the overlay fill the whole viewport.
The div
inside the overlay is instead just in position: static
then the vertical scrollbar you see is related to that element. As a result the content is scrollable but overlay remains fixed.
When you close the zoom you hide the overlay (via display: none
) and then you could also entirely remove it via javascript (or just the content inside, it's up to you how to inject it).
As a final step you have to also remove the noscroll
class to the body
(so the overflow property returns to its initial value)
Code
Codepen Example
(it works by changing the aria-hidden
attribute of the overlay in order to show and hide it and to increase its accessibility).
Markup
(open button)
<button type="button" class="open-overlay">OPEN LAYER</button>
(overlay and close button)
<section class="overlay" aria-hidden="true">
<div>
<h2>Hello, I'm the overlayer</h2>
...
<button type="button" class="close-overlay">CLOSE LAYER</button>
</div>
</section>
CSS
.noscroll {
overflow: hidden;
}
.overlay {
position: fixed;
overflow-y: scroll;
top: 0; right: 0; bottom: 0; left: 0; }
[aria-hidden="true"] { display: none; }
[aria-hidden="false"] { display: block; }
Javascript (vanilla-JS)
var body = document.body,
overlay = document.querySelector('.overlay'),
overlayBtts = document.querySelectorAll('button[class$="overlay"]');
[].forEach.call(overlayBtts, function(btt) {
btt.addEventListener('click', function() {
/* Detect the button class name */
var overlayOpen = this.className === 'open-overlay';
/* Toggle the aria-hidden state on the overlay and the
no-scroll class on the body */
overlay.setAttribute('aria-hidden', !overlayOpen);
body.classList.toggle('noscroll', overlayOpen);
/* On some mobile browser when the overlay was previously
opened and scrolled, if you open it again it doesn't
reset its scrollTop property */
overlay.scrollTop = 0;
}, false);
});
Finally, here's another example in which the overlay opens with a fade-in effect by a CSS transition
applied to the opacity
property. Also a padding-right
is applied to avoid a reflow on the underlying text when the scrollbar disappears.
Codepen Example (fade)
CSS
.noscroll { overflow: hidden; }
@media (min-device-width: 1025px) {
/* not strictly necessary, just an experiment for
this specific example and couldn't be necessary
at all on some browser */
.noscroll {
padding-right: 15px;
}
}
.overlay {
position: fixed;
overflow-y: scroll;
top: 0; left: 0; right: 0; bottom: 0;
}
[aria-hidden="true"] {
transition: opacity 1s, z-index 0s 1s;
width: 100vw;
z-index: -1;
opacity: 0;
}
[aria-hidden="false"] {
transition: opacity 1s;
width: 100%;
z-index: 1;
opacity: 1;
}
Disable Scrolling on Body
Set height
and overflow
:
html, body {margin: 0; height: 100%; overflow: hidden}
http://jsfiddle.net/q99hvawt/
Deactivate body's scrolling but keep scroll bar
This is the only CSS you will ned to force the scrollbars:
html{
overflow-y: scroll;
}
The scrollbars will be disabled if the content is smaller than the window, so you will have to use some script to resize the body to be at least 1px
less then the window height:
$("body").css({ "height" : ($(window).height() - 1) + 'px', "overflow": "hidden" });
Disable horizontal scrolling without overflow hidden
Simply remove all the width you specified as this is the default behavior of block element to take 100% of width. And you need to pay attention as 100vh is not equal to 100%. The first one include the calculation of scrollbar :
* { margin: 0; padding: 0; box-sizing: border-box; max-width: 100vw; font-family: 'Montserrat', sans-serif; font-weight: 400;}
#nav { height: 100px; padding: 0 2vw; font-weight: 700;}
.p5_container { height: calc(100vh - 100px - 150px); background-color: beige;}
.arrow { height: 150px; background-color: #6195B2;}
<body> <header id="nav"> <ul> <li><a href="#">Circle</a></li> <li><a href="#">Square</a></li> <li><a href="#">Line</a></li> </ul> </header>
<div id="p5_banner" class="p5_container"></div>
<div class="arrow"></div> <div id="p5_circle" class="p5_container"></div>
<div class="arrow"></div> <div id="p5_square" class="p5_container"></div>
<div class="arrow"></div> <div id="p5_line" class="p5_container"></div></body>
Related Topics
Why Is It Bad Practice to Use Links With the JavaScript: "Protocol"
Chrome Counts Characters Wrong in Textarea With Maxlength Attribute
In Jquery, How to Select an Element by Its Name Attribute
Adding Additional Data to Select Options Using Jquery
How to Include CSS and Js Files Via Https When Needed
How to Check If a Scrollbar Is Visible
How to Access CSS Generated Content With JavaScript
Why Pass Parameters to CSS and JavaScript Link Files Like Src="../Cnt.Jsver=4.0"
Why Is My Variable Unaltered After I Modify It Inside of a Function? - Asynchronous Code Reference
How to Use a Variable For a Key in a JavaScript Object Literal
Confirmation Before Closing of Tab/Browser
Cross-Origin Data in Html5 Canvas
How to Prevent JavaScript Injection Attacks Within User-Generated Html
Why Is ≪Marquee≫ Deprecated and What Is the Best Alternative
Setting Background-Image Using Jquery CSS Property