如何暂时禁用滚动?

我正在使用scrollTo jQuery插件,想知道是否有可能通过Javascript暂时禁用窗口元素上的滚动?我想禁用滚动的原因是,当你滚动而scrollTo是动画,它变得非常难看;)

当然,我可以执行$("body").css("overflow", "hidden");,然后在动画停止时将其置为auto,但如果滚动条仍然可见但处于非活动状态会更好。

1041012 次浏览

这里有一个非常基本的方法:

window.onscroll = function () { window.scrollTo(0, 0); };

在IE6中有点不稳定。

scroll事件不能取消。但是你可以通过取消这些交互事件:
鼠标 , 触摸滚动按钮关联滚动。

(演示工作)

// left: 37, up: 38, right: 39, down: 40,
// spacebar: 32, pageup: 33, pagedown: 34, end: 35, home: 36
var keys = {37: 1, 38: 1, 39: 1, 40: 1};


function preventDefault(e) {
e.preventDefault();
}


function preventDefaultForScrollKeys(e) {
if (keys[e.keyCode]) {
preventDefault(e);
return false;
}
}


// modern Chrome requires { passive: false } when adding event
var supportsPassive = false;
try {
window.addEventListener("test", null, Object.defineProperty({}, 'passive', {
get: function () { supportsPassive = true; }
}));
} catch(e) {}


var wheelOpt = supportsPassive ? { passive: false } : false;
var wheelEvent = 'onwheel' in document.createElement('div') ? 'wheel' : 'mousewheel';


// call this to Disable
function disableScroll() {
window.addEventListener('DOMMouseScroll', preventDefault, false); // older FF
window.addEventListener(wheelEvent, preventDefault, wheelOpt); // modern desktop
window.addEventListener('touchmove', preventDefault, wheelOpt); // mobile
window.addEventListener('keydown', preventDefaultForScrollKeys, false);
}


// call this to Enable
function enableScroll() {
window.removeEventListener('DOMMouseScroll', preventDefault, false);
window.removeEventListener(wheelEvent, preventDefault, wheelOpt);
window.removeEventListener('touchmove', preventDefault, wheelOpt);
window.removeEventListener('keydown', preventDefaultForScrollKeys, false);
}

更新:固定Chrome桌面和现代移动浏览器被动监听器

我很抱歉回答一个旧帖子,但我正在寻找一个解决方案,遇到了这个问题。

对于这个问题,仍然有许多变通办法来显示滚动条,比如给容器100%的高度和overflow-y: scroll样式。

在我的例子中,我只是创建了一个带有滚动条的div,并在将overflow: hidden添加到正文时显示该滚动条:

function disableScroll() {
document.getElementById('scrollbar').style.display = 'block';
document.body.style.overflow = 'hidden';
}

元素滚动条必须具有以下样式:

overflow-y: scroll; top: 0; right: 0; display: none; height: 100%; position: fixed;

这显示了一个灰色的滚动条,希望它有助于未来的访问者。

我找到了一个更好,但有问题的方法,结合了sdleihssirhc的想法:

window.onscroll = function() {
window.scrollTo(window.scrollX, window.scrollY);
//Or
//window.scroll(window.scrollX, window.scrollY);
//Or Fallback
//window.scrollX=window.scrollX;
//window.scrollY=window.scrollY;
};

我没有测试它,但我稍后会编辑,让你们都知道。我有85%的把握它能在主流浏览器上运行。

只需在body中添加一个类即可:

.stop-scrolling {
height: 100%;
overflow: hidden;
}

添加类,然后删除当你想重新启用滚动,测试在IE, FF, Safari和Chrome。

$('body').addClass('stop-scrolling')

对于移动设备,你需要处理touchmove事件:

$('body').bind('touchmove', function(e){e.preventDefault()})

并取消绑定以重新启用滚动。在iOS6和Android 2.3.3测试

$('body').unbind('touchmove')

这个怎么样?(如果你正在使用jQuery)

var $window = $(window);
var $body = $(window.document.body);


window.onscroll = function() {
var overlay = $body.children(".ui-widget-overlay").first();


// Check if the overlay is visible and restore the previous scroll state
if (overlay.is(":visible")) {
var scrollPos = $body.data("scroll-pos") || { x: 0, y: 0 };
window.scrollTo(scrollPos.x, scrollPos.y);
}
else {
// Just store the scroll state
$body.data("scroll-pos", { x: $window.scrollLeft(), y: $window.scrollTop() });
}
};

我在另一个网站上找到了这个答案:

禁用滚动:

$( ".popup").live({
popupbeforeposition: function(event, ui) {
$("body").on("touchmove", false);
}
});

关闭后弹出窗口释放滚动:

$( ".popup" ).live({
popupafterclose: function(event, ui) {
$("body").unbind("touchmove");
}
});

根据你想要使用移除的滚动来实现什么,你可以只修复你想要移除滚动的元素(单击,或任何其他你想要临时禁用滚动的触发器)

我正在寻找一个“临时无滚动”的解决方案,这解决了我的需要

创建一个班级

.fixed{
position: fixed;
}

然后用Jquery

var someTrigger = $('#trigger'); //a trigger button
var contentContainer = $('#content'); //element I want to temporarily remove scroll from


contentContainer.addClass('notfixed'); //make sure that the element has the "notfixed" class


//Something to trigger the fixed positioning. In this case we chose a button.
someTrigger.on('click', function(){


if(contentContainer.hasClass('notfixed')){
contentContainer.removeClass('notfixed').addClass('fixed');


}else if(contentContainer.hasClass('fixed')){
contentContainer.removeClass('fixed').addClass('notfixed');
};
});

我发现这是一个非常简单的解决方案,适用于所有浏览器,也适用于便携式设备(如iphone,平板电脑等)。由于元素是临时固定的,所以没有滚动:)

注意!根据contentContainer元素的位置,你可能需要从左边调整它。这可以很容易地通过添加一个css左值的元素时,固定类是活跃的

contentContainer.css({
'left': $(window).width() - contentContainer.width()/2 //This would result in a value that is the windows entire width minus the element we want to "center" divided by two (since it's only pushed from one side)
});

根据galambalazs的帖子,我将添加对触摸设备的支持,允许我们触摸但不能上下滚动:

function disable_scroll() {
...
document.ontouchmove = function(e){
e.preventDefault();
}
}


function enable_scroll() {
...
document.ontouchmove = function(e){
return true;
}
}

另一个解决方案:

body {
overflow-y: scroll;
width: 100%;
margin: 0 auto;
}

这样你总是有一个垂直的滚动条,但由于我的大部分内容都比视口长,这对我来说是可以的。内容是中心与一个单独的div,但没有设置边缘再次在身体我的内容将留在左边。

这是我用来显示弹出式/模态的两个函数:

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);
}

结果:不可滚动的背景和没有重新定位的内容,因为左边的滚动条。测试与当前的FF, Chrome和IE 10。

这个解决方案将保持当前的滚动位置,而滚动是禁用的,不像有些跳回用户顶部。

它是基于galambalazs的回答,但支持触摸设备,并重构为一个单一的对象与jquery插件包装。

Demo here.

在github这里

/**
* $.disablescroll
* Author: Josh Harrison - aloof.co
*
* Disables scroll events from mousewheels, touchmoves and keypresses.
* Use while jQuery is animating the scroll position for a guaranteed super-smooth ride!
*/


;(function($) {


"use strict";


var instance, proto;


function UserScrollDisabler($container, options) {
// spacebar: 32, pageup: 33, pagedown: 34, end: 35, home: 36
// left: 37, up: 38, right: 39, down: 40
this.opts = $.extend({
handleKeys : true,
scrollEventKeys : [32, 33, 34, 35, 36, 37, 38, 39, 40]
}, options);


this.$container = $container;
this.$document = $(document);
this.lockToScrollPos = [0, 0];


this.disable();
}


proto = UserScrollDisabler.prototype;


proto.disable = function() {
var t = this;


t.lockToScrollPos = [
t.$container.scrollLeft(),
t.$container.scrollTop()
];


t.$container.on(
"mousewheel.disablescroll DOMMouseScroll.disablescroll touchmove.disablescroll",
t._handleWheel
);


t.$container.on("scroll.disablescroll", function() {
t._handleScrollbar.call(t);
});


if(t.opts.handleKeys) {
t.$document.on("keydown.disablescroll", function(event) {
t._handleKeydown.call(t, event);
});
}
};


proto.undo = function() {
var t = this;
t.$container.off(".disablescroll");
if(t.opts.handleKeys) {
t.$document.off(".disablescroll");
}
};


proto._handleWheel = function(event) {
event.preventDefault();
};


proto._handleScrollbar = function() {
this.$container.scrollLeft(this.lockToScrollPos[0]);
this.$container.scrollTop(this.lockToScrollPos[1]);
};


proto._handleKeydown = function(event) {
for (var i = 0; i < this.opts.scrollEventKeys.length; i++) {
if (event.keyCode === this.opts.scrollEventKeys[i]) {
event.preventDefault();
return;
}
}
};




// Plugin wrapper for object
$.fn.disablescroll = function(method) {


// If calling for the first time, instantiate the object and save
// reference. The plugin can therefore only be instantiated once per
// page. You can pass options object in through the method parameter.
if( ! instance && (typeof method === "object" || ! method)) {
instance = new UserScrollDisabler(this, method);
}


// Instance already created, and a method is being explicitly called,
// e.g. .disablescroll('undo');
else if(instance && instance[method]) {
instance[method].call(instance);
}


};


// Global access
window.UserScrollDisabler = UserScrollDisabler;


})(jQuery);

您可以阻止空格条滚动和隐藏浏览器滚动条:

$(document).keydown(function(event) {
if (event.keyCode == 32) {
return false;


}
});


document.documentElement.style.overflow = 'hidden';
document.body.scroll = 'no';

我知道这是一个老问题,但我不得不做一些非常相似的事情,在花了一段时间寻找答案并尝试了不同的方法后,我最终使用了一个非常简单的解决方案。

我的问题非常相似,几乎相同,唯一的区别是我不需要实际显示滚动条-我只需要确保它的宽度仍然被使用,所以当我的覆盖显示时,页面的宽度不会改变。

当我开始滑动覆盖到屏幕,我做:

$('body').addClass('stop-scrolling').css('margin-right', 8);

在我将覆盖层从屏幕上滑动后,我这样做:

$('body').removeClass('stop-scrolling').css('margin-right', 0);

重要的是:这是完美的工作,因为我的叠加是定位absoluteright: 0pxvisible

下面的解决方案是基本的纯JavaScript(没有jQuery):

function disableScrolling(){
var x=window.scrollX;
var y=window.scrollY;
window.onscroll=function(){window.scrollTo(x, y);};
}


function enableScrolling(){
window.onscroll=function(){};
}

我正在寻找这个问题的解决方案,但不满意上述任何解决方案(写这个答案的时候),所以我想出了这个解决方案。

CSS

.scrollDisabled {
position: fixed;
margin-top: 0;// override by JS to use acc to curr $(window).scrollTop()
width: 100%;
}

JS

var y_offsetWhenScrollDisabled=0;


function disableScrollOnBody(){
y_offsetWhenScrollDisabled= $(window).scrollTop();
$('body').addClass('scrollDisabled').css('margin-top', -y_offsetWhenScrollDisabled);
}
function enableScrollOnBody(){
$('body').removeClass('scrollDisabled').css('margin-top', 0);
$(window).scrollTop(y_offsetWhenScrollDisabled);
}

galambalazs的解决方案很棒!它在Chrome和Firefox中都非常适合我。它还可以扩展,以防止来自浏览器窗口的任何默认事件。 假设你在画布上做一个应用。你可以这样做:

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;
}
}

然后在你的应用程序中,假设你要处理你自己的事件,比如鼠标、键盘、触摸事件等等。你可以在鼠标进入画布时禁用默认事件,并在鼠标离开时重新启用它们:

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);
}

你甚至可以禁用右键菜单与此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; };
}

使用JavaScript启用以下CSS将有所帮助。我不如这里的其他人好,但这对我很有用。

body {
position: fixed;
overflow-y: scroll;
}

我在移动屏幕上有类似的动画问题,但在笔记本电脑上没有,当尝试使用jquery的animate命令动画一个div时。所以我决定使用一个计时器来频繁地恢复窗口的滚动位置,这样肉眼就能看到文档是静态的。这一解决方案在三星Galaxy-2或iphone-5等小屏幕移动设备上运行良好。

这种方法的主要逻辑:将窗口滚动位置设置为原始滚动位置的定时器应该在jquery animate命令之前启动,然后当动画完成时,我们需要清除这个定时器(original scroll position是动画开始前的位置)。

如果计时器间隔是1 millisecond,这就是我的目标,那么在动画持续时间内,文档实际上是静态的。

//get window scroll position prior to animation
//so we can keep this position during animation
var xPosition = window.scrollX || window.pageXOffset || document.body.scrollLeft;
var yPosition = window.scrollY || window.pageYOffset || document.body.scrollTop;


//NOTE:restoreTimer needs to be global variable
//start the restore timer
restoreTimer = setInterval(function() {
window.scrollTo(xPosition, yPosition);
}, 1);


//animate the element emt
emt.animate({
left: "toggle",
top: "toggle",
width: "toggle",
height: "toggle"
}, 500, function() {
//when animation completes, we stop the timer
clearInterval(restoreTimer);
});

另一个有效的解决方案:根据Mohammad Anini在这篇文章下启用/禁用滚动的答案,我还发现如下所示的修改版本的代码。

//get current scroll position
var xPosition = window.scrollX || window.pageXOffset || document.body.scrollLeft;
var yPosition = window.scrollY || window.pageYOffset || document.body.scrollTop;


//disable scrolling
window.onscroll = function() {
window.scrollTo(xPosition, yPosition);
};


//animate and enable scrolling when animation is completed
emt.animate({
left: "toggle",
top: "toggle",
width: "toggle",
height: "toggle"
}, 500, function() {
//enable scrolling when animation is done
window.onscroll = function() {};
});
我对这个问题的看法还包括对主体宽度的关注,因为当我们用overflow = "hidden"隐藏滚动条时,页面似乎会跳舞。 下面的代码非常适合我,并且是基于Angular的方法
element.bind('mouseenter', function() {
var w = document.body.offsetWidth;
document.body.style.overflow = 'hidden';
document.body.style.width = w + 'px';
});


element.bind('mouseleave', function() {
document.body.style.overflow = 'initial';
document.body.style.width = 'auto';
});

一个对我有用的简单解决方案(暂时禁用窗口滚动)。

基于此提琴:http://jsfiddle.net/dh834zgw/1/

下面的代码片段(使用jquery)将禁用窗口滚动:

 var curScrollTop = $(window).scrollTop();
$('html').toggleClass('noscroll').css('top', '-' + curScrollTop + 'px');

在你的css中:

html.noscroll{
position: fixed;
width: 100%;
top:0;
left: 0;
height: 100%;
overflow-y: scroll !important;
z-index: 10;
}

现在,当你删除模态时,不要忘记删除html标签上的noscroll类:

$('html').toggleClass('noscroll');

我使用showModalDialog,用于显示次要页面为模态对话框。

隐藏主窗口滚动条:

document.body.style.overflow = "hidden";

关闭模态对话框时,显示主窗口滚动条:

document.body.style.overflow = "scroll";

从对话框中访问主窗口中的元素:

parent.document.getElementById('dialog-close').click();

只适用于任何搜索showModalDialog的人:(在原始代码的第29行之后)

document.getElementById('dialog-body').contentWindow.dialogArguments = arg;
document.body.style.overflow = "hidden";//****
document.getElementById('dialog-close').addEventListener('click', function(e) {
e.preventDefault();
document.body.style.overflow = "scroll";//****
dialog.close();
});

在我看来,取消事件是一个可怕的方法:/

相反,我在下面使用了position: fixed; top: -scrollTop();

演示:https://jsfiddle.net/w9w9hthy/5/

从我的jQuery弹出项目:https://github.com/seahorsepip/jPopup

//Freeze page content scrolling
function freeze() {
if($("html").css("position") != "fixed") {
var top = $("html").scrollTop() ? $("html").scrollTop() : $("body").scrollTop();
if(window.innerWidth > $("html").width()) {
$("html").css("overflow-y", "scroll");
}
$("html").css({"width": "100%", "height": "100%", "position": "fixed", "top": -top});
}
}


//Unfreeze page content scrolling
function unfreeze() {
if($("html").css("position") == "fixed") {
$("html").css("position", "static");
$("html, body").scrollTop(-parseInt($("html").css("top")));
$("html").css({"position": "", "width": "", "height": "", "top": "", "overflow-y": ""});
}
}

这段代码考虑了宽度、高度、滚动条和页面跳转问题。

上述代码可能解决的问题:

  • 宽度,当设置位置固定的HTML元素宽度可以小于100%
  • 高度,同上
  • 滚动条,当设置位置固定时,页面内容不再有滚动条,即使它在水平页面跳转之前有滚动条
  • 页面跳转,当设置位置固定时,页面滚动顶部不再有效,导致垂直页面跳转

如果任何人对上面的页面冻结/解冻代码有任何改进,请告诉我,这样我就可以将这些改进添加到我的项目中。

我刚刚整理的一些东西:

jsfiddle

document.onwheel = function(e) {
// get the target element
target = e.target;
// the target element might be the children of the scrollable element
// e.g., "li"s inside an "ul", "p"s inside a "div" etc.
// we need to get the parent element and check if it is scrollable
// if the parent isn't scrollable, we move up to the next parent
while (target.scrollHeight <= target.clientHeight) {
// while looping parents, we'll eventually reach document.body
// since body doesn't have a parent, we need to exit the while loop
if (target == document.body) {
break;
}
target = target.parentElement;
}
// we want this behaviour on elements other than the body
if (target != document.body) {
// if the scrollbar is at the top and yet if it still tries to scroll up
// we prevent the scrolling
if (target.scrollTop <= 0 && e.deltaY < 0) {
e.preventDefault();
}
// similarly, if the scrollbar is at the bottom and it still tries to scroll down
// we prevent it
else if (target.clientHeight + target.scrollTop >= target.scrollHeight && e.deltaY > 0) {
e.preventDefault();
}
}
};
body {
background: gainsboro;
}


#box {
width: 300px;
height: 600px;
padding: 5px;
border: 1px solid silver;
margin: 50px auto;
background: white;
overflow: auto;
}
<div id="box">
<p>
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor
in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
</p>
<p>
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor
in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
</p>
<p>
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor
in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
</p>
<p>
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor
in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
</p>
</div>

建立在夏延福布斯的答案,和一个我发现这里通过fcalderan: 只是禁用滚动不隐藏它? 并修复Hallodom的滚动条消失的问题

CSS:

.preventscroll{
position: fixed;
overflow-y:scroll;
}

JS:

whatever.onclick = function(){
$('body').addClass('preventscroll');
}
whatevertoclose.onclick = function(){
$('body').removeClass('preventscroll');
}

这段代码确实会跳到页面的顶部,但我认为fcalderan的代码有一个解决方案。

从Chrome 56和其他现代浏览器开始,你必须在addEventListener调用中添加passive:false才能使preventDefault工作。所以我用这个来停止手机上的滚动:

function preventDefault(e){
e.preventDefault();
}


function disableScroll(){
document.body.addEventListener('touchmove', preventDefault, { passive: false });
}
function enableScroll(){
document.body.removeEventListener('touchmove', preventDefault, { passive: false });
}

我也有同样的问题,下面是我处理它的方法。

/* file.js */
var body = document.getElementsByTagName('body')[0];
//if window dont scroll
body.classList.add("no-scroll");
//if window scroll
body.classList.remove("no-scroll");


/* file.css */
.no-scroll{
position: fixed;
top: 0;
bottom: 0;
left: 0;
right: 0;
}

希望这对你有所帮助。

最简单的方法是:

$("body").css("overflow", "hidden"); // Remove the scroll bar temporarily

要撤消它:

$("body").css("overflow", "auto");

很容易实现,但唯一的缺点是:

  • 如果页面是居中对齐的(水平),它会向左跳一点。

这是由于滚动条被移除,并且视口变得更宽。

下面是停止滚动的解决方案(不使用jQuery)。我用它来禁用滚动时,侧菜单出现。

<button onClick="noscroll()" style="position:fixed; padding: 8px 16px;">Disable/Enable scroll</button>
<script>
var noscroll_var;
function noscroll(){
if(noscroll_var){
document.getElementsByTagName("html")[0].style.overflowY = "";
document.body.style.paddingRight = "0";
noscroll_var = false
}else{
document.getElementsByTagName("html")[0].setAttribute('style', 'overflow-y: hidden !important');
document.body.style.paddingRight = "17px";
noscroll_var = true
}
}/*noscroll()*/
</script>


<!-- Just to fill the page -->
<script>
for(var i=0; i <= 80; i++){
document.write(i + "<hr>")
}
</script>

我用17px的右填充来补偿滚动条的消失。但这也是有问题的,尤其是对于移动浏览器。通过根据获取条宽来解决。

< a href = " https://codepen。 . io/josep81/pen/jLgdwz" rel="nofollow noreferrer">All together in this pen . .

我在触摸设备上也有类似的问题。向元素添加“touch-action: none”解决了这个问题。

获取更多信息。看看这个:-

https://developer.mozilla.org/en-US/docs/Web/CSS/touch-action

这是目前为止我得到的最简单的解。相信我,其他的我都试过了,这是最简单的。在Windows设备上工作得很好,它将页面从右边推到有空间放置系统滚动条,而IOS设备则不需要浏览器中滚动条的空间。所以通过使用这个,你不需要在右边添加填充,所以当你用CSS隐藏正文或HTML的溢出时页面不会闪烁。

如果你仔细想想,解决方法其实很简单。其思想是在弹出窗口被打开时给window.scrollTop ()相同的确切位置。当窗口调整大小时也要改变这个位置(因为一旦发生这种情况,滚动位置就会改变)。

所以我们开始…

首先,我们创建一个变量,让你知道弹出窗口是打开的,并将其命名为stopWindowScroll。如果我们不这样做,那么你会在你的页面上得到一个未定义变量的错误,并将其设置为0 -不活跃。

$(document).ready(function(){
stopWindowScroll = 0;
});

现在让我们创建一个打开的弹出函数witch可以是你代码中的任何函数,它可以触发你作为插件或自定义使用的任何弹出。在这种情况下,它将是一个简单的自定义弹出窗口,带有一个简单的文档点击功能。

$(document).on('click','.open-popup', function(){
// Saving the scroll position once opening the popup.
stopWindowScrollPosition = $(window).scrollTop();
// Setting the stopWindowScroll to 1 to know the popup is open.
stopWindowScroll = 1;
// Displaying your popup.
$('.your-popup').fadeIn(300);
});

接下来我们要做的就是创建close popup函数,我再重复一遍,这个函数可以是你已经创建的或者在插件中使用的任何函数。重要的是,我们需要这两个函数将stopWindowScroll变量设置为1或0,以知道它何时打开或关闭。

$(document).on('click','.open-popup', function(){
// Setting the stopWindowScroll to 0 to know the popup is closed.
stopWindowScroll = 0;
// Hiding your popup
$('.your-popup').fadeOut(300);
});

然后让我们创建窗口。scroll函数,这样一旦上面提到的stopWindowScroll被设置为1 -激活,我们就可以防止滚动。

$(window).scroll(function(){
if(stopWindowScroll == 1) {
// Giving the window scrollTop() function the position on which
// the popup was opened, this way it will stay in its place.
$(window).scrollTop(stopWindowScrollPosition);
}
});

这是它。除了您自己的页面样式外,不需要CSS来完成此工作。这对我来说很有吸引力,我希望它能帮助到你和其他人。

下面是JSFiddle的一个工作示例:

JS提琴示例 .

如果有帮助,请告诉我。的问候。

在全局变量中存储滚动长度,并在需要时恢复它!

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);
}

不,我不会使用事件处理,因为:

  • 不是所有的事件都能保证到达身体,

  • 选择文本并向下移动实际上是在滚动文档,

  • 如果在分离某事物的阶段出了差错,你就完蛋了。

我通过使用隐藏的文本区域进行复制-粘贴操作来解决这个问题,你猜怎么着,每当我进行复制时,页面就会滚动,因为在内部,我必须在调用document.execCommand('copy')之前选择文本区域。

不管怎样,这就是我的方法,注意setTimeout():

document.body.setAttribute('style','overflow:hidden;');
// do your thing...
setTimeout(function(){document.body.setAttribute('style','overflow:visible;');}, 500);

当滚动条暂时消失时,会出现动量闪烁,但这是可以接受的。

这段代码将工作在Chrome 56和进一步(原来的答案不再工作在Chrome上)。

使用DomUtils.enableScroll()来启用滚动。

使用DomUtils.disableScroll()禁用滚动。

class DomUtils {
// left: 37, up: 38, right: 39, down: 40,
// spacebar: 32, pageup: 33, pagedown: 34, end: 35, home: 36
static keys = { 37: 1, 38: 1, 39: 1, 40: 1 };


static preventDefault(e) {
e = e || window.event;
if (e.preventDefault) e.preventDefault();
e.returnValue = false;
}


static preventDefaultForScrollKeys(e) {
if (DomUtils.keys[e.keyCode]) {
DomUtils.preventDefault(e);
return false;
}
}


static disableScroll() {
document.addEventListener('wheel', DomUtils.preventDefault, {
passive: false,
}); // Disable scrolling in Chrome
document.addEventListener('keydown', DomUtils.preventDefaultForScrollKeys, {
passive: false,
});
}


static enableScroll() {
document.removeEventListener('wheel', DomUtils.preventDefault, {
passive: false,
}); // Enable scrolling in Chrome
document.removeEventListener(
'keydown',
DomUtils.preventDefaultForScrollKeys,
{
passive: false,
}
); // Enable scrolling in Chrome
}
}
var winX = null;
var winY = null;


window.addEventListener('scroll', function () {
if (winX !== null && winY !== null) {
window.scrollTo(winX, winY);
}
});


function disableWindowScroll() {
winX = window.scrollX;
winY = window.scrollY;
}


function enableWindowScroll() {
winX = null;
winY = null;
}

为了防止跳楼,我用了这个

export function toggleBodyScroll(disable) {
if (!window.tempScrollTop) {
window.tempScrollTop = window.pageYOffset;
// save the current position in a global variable so I can access again later


}
if (disable) {
document.body.classList.add('disable-scroll');
document.body.style.top = `-${window.tempScrollTop}px`;
} else {
document.body.classList.remove('disable-scroll');
document.body.style.top = `0px`;
window.scrollTo({top: window.tempScrollTop});
window.tempScrollTop = 0;
}
}


在CSS中

.disable-scroll {
height: 100%;
overflow: hidden;
width: 100%;
position: fixed;
}


CSS

  overflow-y: hidden
}


Javascript
``let body = document.querySelector('body');
if(condition)  {
//disable scroll on the entire body
body?.classList.add("disable-scroll");
}
else {
//to remove the class attrib
body?.removeAttribute("class");
//or to remove the disable-scroll class only
body?.classList.remove("dissble-scroll");
}

这比长代码好多了。容易理解

我在这篇文章中找到了解决方案。在我的上下文中,我希望禁用垂直滚动,当我在一个

像这样=>

let scrollContainer = document.getElementById('scroll-container');
document.getElementById('scroll-container').addEventListener(
"wheel",
(event) => {
event.preventDefault();
scrollContainer.scrollLeft += event.deltaY;
},
{
// allow preventDefault()
passive: false
}
);

网站我继承了,有一个滚动的链接。为了暂时禁用滚动单击特定按钮,这对我来说是有效的:

$(document).ready(function() {
$('button.class-name').click(function(event) {
disableScroll();
setTimeout(enableScroll, 500);
});
});




function disableScroll() {
scrollTop =  window.pageYOffset || document.documentElement.scrollTop;
scrollLeft =  window.pageXOffset || document.documentElement.scrollLeft,


window.onscroll = function() {
window.scrollTo(scrollLeft, scrollTop);
};
}


function enableScroll() {
window.onscroll = function() {};
}

我在这里用了一个简单的技巧:

.no-scroll{
overflow: hidden;
}


let toggle_scrolling_state = () => {
element.classList.toggle("no-scroll");
}


然后当你想要停止滚动事件或…

对我来说,这并没有带来任何内容跳跃。

禁用滚动:

this.htmlBody = $('body')
this.scrollPos = document.documentElement.scrollTop
this.htmlBody.css('top', -this.scrollPos + 'px').addClass('disable-scroll')

重新启用滚动:

this.htmlBody.removeClass('disable-scroll')
$(window).scrollTop(this.scrollPos)

而CSS:

body.disable-scroll {
position: fixed;
width: 100%;
}

使用Javascript函数切换overflowY,同时切换移动菜单的可见性。比如这个:

function handleClickMobileMenu() {
document.body.style.overflowY = isMobileMenuOpen ? "hidden" : "scroll";
//...
}

当你打开和关闭移动菜单时调用这个函数。 最好的用例是当你的手机菜单占据整个视口区域

这个答案提出了一个消除“肿块”的解决方案。当应用这个解决方案中建议的overflow: hidden时发生。由于编辑被拒绝,下面是:


对于overflow: hidden应用时发生的去掉“肿块”;,您可以计算滚动条的宽度并将其替换为margin。下面是body元素的例子:

const bodyScrollControls = {
scrollBarWidth: window.innerWidth - document.body.clientWidth,


disable() {
document.body.style.marginRight = `${this.scrollBarWidth}px`;
document.body.style.overflowY = 'hidden';
},
enable() {
document.body.style.marginRight = null;
document.body.style.overflowY = null;
},
};

如果一个元素已经有margin-right,获取现有的一个并为其添加滚动条宽度应该不是问题。

我发现改变身体的风格是没有必要的。

我们唯一需要做的就是防止整个文档(html元素)出现y滚动。

我们可以用Javascript来创建和销毁样式表。我是这样做的:

https://jsfiddle.net/3os72ryk/

var scroll_style_element;


function disable_scrolling(){
    

// Create a style sheet we will only use to disable scrolling :
scroll_style_element = document.createElement('style');
document.head.appendChild(scroll_style_element);
const scroll_style_sheet = scroll_style_element.sheet;
    

scroll_style_sheet.insertRule('html{height:100%;overflow-y:hidden;}', scroll_style_sheet.cssRules.length);
}


function enable_scrolling(){
if( scroll_style_element ) document.head.removeChild(scroll_style_element);
}

非常有兴趣知道是否有人发现这种方法有问题,所以如果你发现了,请在下面评论。

你可以这样做:

这样可以节省“无关紧要”的内存,并且带有Position: fixed的元素不会移动,因此不会影响你的设计本身。

CSS(使用CSS让你的生活和记忆更容易)

html[DisableScroll] {
overflow-y: scroll;
}


html[DisableScroll] body {
overflow-y: hidden;
height: 100vh;
}

JS

var enableScroll = function () {
document.documentElement
.removeAttribute('DisableScroll');
}

//When you want to enable escroll just call this function;


var enableScroll = function () {
document.documentElement
.removeAttribute('DisableScroll');
}
 

setTimeout(() => {
enableScroll();
}, 2000);
*{
margin: 0px;
padding: 0px
}
body{
height: 4000px;
background: #141417
}


html[DisableScroll] {
overflow-y: scroll
}


html[DisableScroll] body {
overflow-y: hidden;
height: 100vh;
}
body>p{
color: #FBFBFD
}


div{
position: fixed;
left: 0;
right: 0;
margin: auto;
width: 270px;
background: #FBFBFD;
color: #141417;
text-align: center
} 
<!DOCTYPE html>
<html lang="en" DisableScroll>
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<div>
<p>@@@@</p><br>
<p>@@@@</p><br>
<p>@@@@</p><br>
<p>@@@@</p><br>
<p>@@@@</p><br>
<p>@@@@</p><br>
<p>@@@@</p><br>
<p>@@@@</p><br>
<p>@@@@</p><br>
<p>@@@@</p><br>
<p>@@@@</p><br>
<p>@@@@</p><br>
<p>@@@@</p><br>
<p>@@@@</p><br>
<p>@@@@</p><br>
<p>@@@@</p><br>
<p>@@@@</p><br>
<p>@@@@</p><br>
<p>@@@@</p><br>
<p>@@@@</p><br>
<p>@@@@</p><br>
<p>@@@@</p><br>
<p>@@@@</p><br>
<p>@@@@</p><br>
<p>@@@@</p><br>
<p>@@@@</p><br>
<p>@@@@</p><br>
<p>@@@@</p><br>
<p>@@@@</p><br>
<p>@@@@</p><br>
<p>@@@@</p><br>
<p>@@@@</p><br>
<p>@@@@</p><br>
<p>@@@@</p><br>
<p>@@@@</p><br>
<p>@@@@</p><br>
<p>@@@@</p><br>
<p>@@@@</p><br>
<p>@@@@</p><br>
<p>@@@@</p><br>
<p>@@@@</p><br>
<p>@@@@</p><br>
<p>@@@@</p><br>
<p>@@@@</p><br>
<p>@@@@</p><br>
<p>@@@@</p><br>
<p>@@@@</p><br>
<p>@@@@</p><br>
<p>@@@@</p><br>
<p>@@@@</p><br>
<p>@@@@</p><br>
<p>@@@@</p><br>
<p>@@@@</p><br>
<p>@@@@</p><br>
<p>@@@@</p><br>
<p>@@@@</p><br>
</div>
<p>@@@@</p><br>
<p>@@@@</p><br>
<p>@@@@</p><br>
<p>@@@@</p><br>
<p>@@@@</p><br>
<p>@@@@</p><br>
<p>@@@@</p><br>
<p>@@@@</p><br>
<p>@@@@</p><br>
<p>@@@@</p><br>
<p>@@@@</p><br>
<p>@@@@</p><br>
<p>@@@@</p><br>
<p>@@@@</p><br>
<p>@@@@</p><br>
<p>@@@@</p><br>
<p>@@@@</p><br>
<p>@@@@</p><br>
<p>@@@@</p><br>
<p>@@@@</p><br>
<p>@@@@</p><br>
<p>@@@@</p><br>
<p>@@@@</p><br>
<p>@@@@</p><br>
<p>@@@@</p><br>
<p>@@@@</p><br>
<p>@@@@</p><br>
<p>@@@@</p><br>
<p>@@@@</p><br>
<p>@@@@</p><br>
<p>@@@@</p><br>
<p>@@@@</p><br>
<p>@@@@</p><br>
<p>@@@@</p><br>
<p>@@@@</p><br>
<p>@@@@</p><br>
<p>@@@@</p><br>
<p>@@@@</p><br>
<p>@@@@</p><br>
<p>@@@@</p><br>
<p>@@@@</p><br>
<p>@@@@</p><br>
<p>@@@@</p><br>
<p>@@@@</p><br>
<p>@@@@</p><br>
<p>@@@@</p><br>
<p>@@@@</p><br>
<p>@@@@</p><br>
<p>@@@@</p><br>
<p>@@@@</p><br>
<p>@@@@</p><br>
<p>@@@@</p><br>
<p>@@@@</p><br>
<p>@@@@</p><br>
<p>@@@@</p><br>
<p>@@@@</p><br>
</body>
</html>

另一个解决方案!

而不是使用多个事件监听器和添加,停止和关闭它们,你可以用回调只添加一次监听器,在其中你可以在函数中共享事件,只在需要的时候和地方调用preventDefault等等,甚至实现自己的事件优先级系统。