如何使用jQuery编程禁用页面滚动

174

使用jQuery,我想要禁用页面的滚动:

我的想法是:

  1. 设置 body{ overflow: hidden;}
  2. 获取当前的 scrollTop();/scrollLeft()
  3. 绑定到 body 滚动事件上,将 scrollTop/scrollLeft 设置为已获取的值。

还有更好的方法吗?


更新:

请在 http://jsbin.com/ikuma4/2/edit 中查看我的示例以及原因。

我知道有人会想“为什么他不只是在面板上使用position: fixed呢?”

请不要建议此方法,因为我有其他原因。


7
除了让浏览器正常运行,有更好的方法吗? - Fenton
23
夸张地感情用事的。 - Mike Weller
6
也许是指编程上的?因为这是Firefox针对"programatically"的拼写纠正建议。 - Michael Shimmins
4
这个帖子即将结束。 - Cipi
4
@Sohnee 禁用滚动并不等同于不好。 - Mansiemans
显示剩余12条评论
24个回答

257

这将完全禁用滚动:

$('html, body').css({
    overflow: 'hidden',
    height: '100%'
});

恢复:

$('html, body').css({
    overflow: 'auto',
    height: 'auto'
});

在Firefox和Chrome上测试过了。


7
在Chrome浏览器上仍可使用鼠标中键滚动页面。 - Lothar
18
这将导致当前滚动位置丢失。 OP明确提到了捕获滚动位置,因此我认为他需要这个功能。无论如何,我需要它,所以对我来说有限的用处。 - zerm
10
省略 height: 100% 可以有效地锁定滚动条在当前位置,而不会出现跳跃 - 至少在最新版的 Chrome 浏览器上是这样。 - zerm
2
这不是正确的答案。滚动位置没有被捕获。 - taylorcressy
1
非常好用,这刚刚提醒了我“html”和“body”同等重要。 - Anjana Silva
显示剩余13条评论

147

我找到的唯一方法与您描述的类似:

  1. 获取当前滚动位置(不要忘记水平轴!)。
  2. 将溢出设置为hidden(可能需要保留以前的溢出值)。
  3. 使用scrollTo()将文档滚动到存储的滚动位置。

然后,当您准备好再次允许滚动时,撤销所有操作。

编辑:由于我费了很大力气去挖代码,所以没有理由不给您代码...

// lock scroll position, but retain settings for later
var scrollPosition = [
  self.pageXOffset || document.documentElement.scrollLeft || document.body.scrollLeft,
  self.pageYOffset || document.documentElement.scrollTop  || document.body.scrollTop
];
var html = jQuery('html'); // it would make more sense to apply this to body, but IE7 won't have that
html.data('scroll-position', scrollPosition);
html.data('previous-overflow', html.css('overflow'));
html.css('overflow', 'hidden');
window.scrollTo(scrollPosition[0], scrollPosition[1]);


// un-lock scroll position
var html = jQuery('html');
var scrollPosition = html.data('scroll-position');
html.css('overflow', html.data('previous-overflow'));
window.scrollTo(scrollPosition[0], scrollPosition[1])

2
请查看http://jsbin.com/ikuma4/2/edit并向我解释您的回答为什么更好?我是否遗漏了什么(我问这个问题是因为我看不出您的回答长度与我的示例相比有何优势)。 - Hailwood
3
你的方法在IE7中不起作用。我也尝试了那个方法。问题在于它没有及时响应滚动事件。它会让文档滚动,然后当你的JS将滚动位置重置回你想要的位置时,它会将其弹回。 - tfe
1
另外,如果 body 的任何溢出内容不是 auto,它都将被覆盖。我需要保留现有的设置,这也增加了一些开销。 - tfe
4
这是一个很棒的回答。为了使它在触摸设备上正常工作,请查看这个回答。 - Patrick
在编程中,使用“html”只适用于IE浏览器。而在Chrome浏览器中需要使用“body”。 - Pablo
显示剩余5条评论

47

试一试

$('#element').on('scroll touchmove mousewheel', function(e){
  e.preventDefault();
  e.stopPropagation();
  return false;
})

正是我正在寻找的...几乎。无论如何,在箭头键期间有办法禁用它吗? - Cody
2
@Cody - 将此与 css overflow: hidden 结合使用。 - Dariux
2
@cubbiu 怎么翻转它? - Meer
3
дҪ еҸҜд»ҘдҪҝз”Ё$('#element').off('scroll touchmove mousewheel');гҖӮиҝҷиЎҢд»Јз Ғзҡ„дҪңз”ЁжҳҜеҸ–ж¶Ҳз»‘е®ҡеңЁ#elementе…ғзҙ дёҠзҡ„ж»ҡеҠЁгҖҒи§Ұ摸移еҠЁе’Ңйј ж Үж»ҡиҪ®дәӢ件гҖӮ - arnuschky
2
很好的解决方案。但是如何仅禁用body滚动,同时允许在具有overflow:scroll的其他子元素中滚动呢? - Fizzix
我尝试了所有可能的解决方案,只有这个有效,非常感谢! - user10368025

28

我对tfe的解决方案进行了一些微调。特别地,我添加了一些额外的控制来确保在将滚动条设置为hidden时,页面内容不会发生偏移(也称为页面偏移)。

可以定义两个JavaScript函数lockScroll()unlockScroll(),分别用于锁定和解锁页面滚动。

function lockScroll(){
    $html = $('html'); 
    $body = $('body'); 
    var initWidth = $body.outerWidth();
    var initHeight = $body.outerHeight();

    var scrollPosition = [
        self.pageXOffset || document.documentElement.scrollLeft || document.body.scrollLeft,
        self.pageYOffset || document.documentElement.scrollTop  || document.body.scrollTop
    ];
    $html.data('scroll-position', scrollPosition);
    $html.data('previous-overflow', $html.css('overflow'));
    $html.css('overflow', 'hidden');
    window.scrollTo(scrollPosition[0], scrollPosition[1]);   

    var marginR = $body.outerWidth()-initWidth;
    var marginB = $body.outerHeight()-initHeight; 
    $body.css({'margin-right': marginR,'margin-bottom': marginB});
} 

function unlockScroll(){
    $html = $('html');
    $body = $('body');
    $html.css('overflow', $html.data('previous-overflow'));
    var scrollPosition = $html.data('scroll-position');
    window.scrollTo(scrollPosition[0], scrollPosition[1]);    

    $body.css({'margin-right': 0, 'margin-bottom': 0});
}

我假设 <body> 没有初始的 margin。

请注意,虽然上述解决方案在大多数实际情况下都有效,但并不是最终的解决方案,因为它需要进一步定制,以适应包含诸如带有 position:fixed 的页眉等页面。让我们通过一个例子来了解这种特殊情况。假设有:

<body>
<div id="header">My fixedheader</div>
<!--- OTHER CONTENT -->
</body>
#header{position:fixed; padding:0; margin:0; width:100%}

然后,在函数lockScroll()unlockScroll()中应添加以下内容:

function lockScroll(){
    //Omissis   


    $('#header').css('margin-right', marginR);
} 

function unlockScroll(){
    //Omissis   

    $('#header').css('margin-right', 0);
}

最后,注意一些可能的边距或填充的初始值。


4
你的JavaScript代码中有一个错误: $body.css({'margin-right': 0, 'margin-bottom', 0}); 应该改为: $body.css({'margin-right': 0, 'margin-bottom': 0}); 请注意,正确的语法应该是冒号而不是逗号来分隔CSS属性和属性值。 - Johansrk
其实,只需要使用 marginRightmarginLeft :) - Martijn

27

你可以使用这段代码:

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

8
您仍然可以使用鼠标中键进行滚动。 - Roger Far
2
不,这样没问题,也不需要滚动! - mr.soroush
如果您使用一些额外的CSS,您可以完全禁用滚动条,请参阅我的答案以获取更多详细信息。 - gitaarik

24

要禁用滚动,请尝试以下方法:

var current = $(window).scrollTop();
$(window).scroll(function() {
    $(window).scrollTop(current);
});

重置:

$(window).off('scroll');

@EveryScreamer 不,它会让屏幕疯狂抖动。正在尝试找到解决方法。 - jarrodwhitley

5

您可以将一个函数附加到滚动事件上,并防止其默认行为。

var $window = $(window);

$window.on("mousewheel DOMMouseScroll", onMouseWheel);

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

https://jsfiddle.net/22cLw9em/


它可以工作。只需要发布复位代码以匹配帕特里克的答案 - Hastig Zusammenstellen

5
我已经编写了一个jQuery插件来处理这个问题: $.disablescroll
它可以防止鼠标滚轮、触摸移动和按键事件(如Page Down)导致页面滚动。
这里有一个演示
使用方法:
$(window).disablescroll();

// To re-enable scrolling:
$(window).disablescroll("undo");

我尝试使用你的disablescroll()插件来暂时禁用滚动,以响应鼠标滚轮/滚动事件,但它没有起作用。你知道有什么方法可以实现这个效果吗? - yellow-saint
@J.B. 我可能可以帮忙,但是评论区不是最好的地方。加入我在这个 Stack Overflow 聊天室,我会看看我能做什么:http://chat.stackoverflow.com/rooms/55043/disablescroll-usage - Josh Harrison
很抱歉,但是这个插件在你的jsfiddle中甚至都无法工作。 - markj
请问您能告诉我在哪个浏览器/平台上无法正常工作吗?这样您就可以帮助我检查了。 - Josh Harrison

4
一行代码禁用滚动,包括鼠标中键。

$(document).scroll(function () { $(document).scrollTop(0); });

编辑:无论如何都没有必要使用jQuery,下面的代码可以用原生JavaScript实现(意味着不需要框架,只使用JavaScript):

document.addEventListener('scroll', function () { this.documentElement.scrollTop = 0; this.body.scrollTop = 0; })

this.documentElement.scrollTop - 标准模式

this.body.scrollTop - 兼容IE模式


4
  • 隐藏滚动条:$("body").css("overflow", "hidden");
  • 恢复滚动条:$("body").css("overflow", "initial");
这段代码是关于控制网页滚动条的。第一行代码可以隐藏网页滚动条,第二行代码则可以恢复滚动条。请注意,在代码中保留了html标签。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接