I\'m using the scrollTo jQuery plugin and would like to know if it is somehow possible to temporarily disable scrolling on the window element through Javascript? The reason
The following solution is basic but pure JavaScript (no jQuery):
function disableScrolling(){
var x=window.scrollX;
var y=window.scrollY;
window.onscroll=function(){window.scrollTo(x, y);};
}
function enableScrolling(){
window.onscroll=function(){};
}
Another solution:
body {
overflow-y: scroll;
width: 100%;
margin: 0 auto;
}
This way you always have a vertical scrollbar, but as most of my content is longer than the viewport, this is ok for me. Content is centered with a separate div, but without setting margin again in body my content would stay at the left.
These are the two function I use to show my popup/modal:
var popup_bodyTop = 0;
var popup_bodyLeft = 0;
function popupShow(id)
{
$('#'+ id).effect('fade');
$('#popup-overlay').effect('fade');
// remember current scroll-position
// because when setting/unsetting position: fixed to body
// the body would scroll to 0,0
popup_bodyLeft = $(document).scrollLeft();
popup_bodyTop = $(document).scrollTop();
// invert position
var x = - popup_bodyLeft;
var y = - popup_bodyTop;
$('body').css('position', 'fixed');
$('body').css('top', y.toString() +'px');
$('body').css('left', x.toString() +'px');
}
function popupHide(id)
{
$('#'+ id).effect('fade');
$('#popup-overlay').effect('fade');
$('body').css('position', '');
$('html, body').scrollTop(popup_bodyTop);
$('html, body').scrollLeft(popup_bodyLeft);
}
Result: non scrollable background and no re-positioning of the content because of the left scrollbar. Tested with current FF, Chrome and IE 10.
galambalazs's solution is great! It worked perfectly for me in both Chrome and Firefox. And it also may be extended to prevent any default event from the browser window. Let's say you are doing an app on the canvas. You could do this:
var events = {
preventDefault: function(e) {
e = e || window.event;
if (e.preventDefault) e.preventDefault();
e.returnValue = false;
},
//spacebar: 32, pageup: 33, pagedown: 34, end: 35, home: 36,
//left: 37, up: 38, right: 39, down: 40
keys: [32, 33, 34, 35, 36, 37, 38, 39, 40],
keydown: function(e) {
for (var i = events.keys.length; i--;) {
if (e.keyCode === events.keys[i]) {
events.preventDefault(e);
return;
}
}
},
wheel: function(e) {
events.preventDefault(e);
},
disable: function() {
if (window.addEventListener) {
window.addEventListener('DOMMouseScroll', events.wheel, false);
}
window.onmousewheel = document.onmousewheel = events.wheel;
document.onkeydown = helpers.events.keydown;
},
enable: function() {
if (window.removeEventListener) {
window.removeEventListener('DOMMouseScroll', events.wheel, false);
}
window.onmousewheel = document.onmousewheel = document.onkeydown = null;
}
}
And then on your app let's say you're going to process your own events, like mouse, keyboard, touch events and so on... You could disable default events when the mouse goes inside the canvas and re-enable them when the mouse goes out:
function setMouseEvents(canvas) {
var useCapture = false;
//Mouse enter event
canvas.addEventListener('mouseenter', function(event) {
events.disable();
}, useCapture);
//Mouse leave event
canvas.addEventListener('mouseleave', function(event) {
events.enable();
}, useCapture);
}
You could even disable right click menu with this hack:
function disableRightClickMenu(canvas) {
var my_gradient = canvas.context.createLinearGradient(0, 0, 0, 225);
my_gradient.addColorStop(0, "white");
my_gradient.addColorStop(1, "white");
canvas.context.fillStyle = my_gradient;
canvas.context.fillRect(0, 0, canvas.width, canvas.height);
canvas.oncontextmenu = function() { return false; };
}
No, I wouldn't go with event handling because:
not all events are guaranteed to reach body,
selecting text and moving downwards actually scrolls the document,
if at the phase of event detaching sth goes wrong you are doomed.
I've bitten by this by making a copy-paste action with a hidden textarea and guess what, the page scroll whenever I make copy because internally I have to select the textarea before I call document.execCommand('copy')
.
Anyway that's the way I go, notice the setTimeout()
:
document.body.setAttribute('style','overflow:hidden;');
// do your thing...
setTimeout(function(){document.body.setAttribute('style','overflow:visible;');}, 500);
A momentum flashing exists as the scrollbars disappear momentarily but it's acceptable I thing.
Building on Cheyenne Forbes' answer, and one I found here via fcalderan: Just disable scroll not hide it? and to fix Hallodom's issue of the scrollbar disappearing
CSS:
.preventscroll{
position: fixed;
overflow-y:scroll;
}
JS:
whatever.onclick = function(){
$('body').addClass('preventscroll');
}
whatevertoclose.onclick = function(){
$('body').removeClass('preventscroll');
}
This code does jump you to the top of the page, but I think that fcalderan's code has a workaround.
Store scroll length in a global variable and restore it when needed!
var sctollTop_length = 0;
function scroll_pause(){
sctollTop_length = $(window).scrollTop();
$("body").css("overflow", "hidden");
}
function scroll_resume(){
$("body").css("overflow", "auto");
$(window).scrollTop(sctollTop_length);
}