如何使用 jQuery 以编程方式禁用页面滚动
Posted
技术标签:
【中文标题】如何使用 jQuery 以编程方式禁用页面滚动【英文标题】:How to programmatically disable page scrolling with jQuery 【发布时间】:2011-04-09 01:37:07 【问题描述】:使用 jQuery,我想禁用正文的滚动:
我的想法是:
-
设置
body overflow: hidden;
捕获当前scrollTop();/scrollLeft()
绑定到body滚动事件,设置scrollTop/scrollLeft为捕获的值。
有没有更好的办法?
更新:
请在http://jsbin.com/ikuma4/2/edit查看我的示例以及原因
我知道有人会想“他为什么不在面板上使用position: fixed
?”。
请不要这样建议,因为我有其他原因。
【问题讨论】:
"有更好的方法吗?" - 除了让浏览器正常运行吗? “戏剧性地”? 也许是程序化的意思?因为它是 'programatically' 的 Firefox ***拼写更正建议 这个线程正在运行\b\ @Sohnee 禁用滚动!== 错误 【参考方案1】:我发现这样做的唯一方法与您描述的类似:
-
获取当前滚动位置(不要忘记水平轴!)。
将溢出设置为隐藏(可能希望保留以前的溢出值)。
使用 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])
【讨论】:
请参阅jsbin.com/ikuma4/2/edit 并向我解释您的更好的任何理由?我是否遗漏了什么(我问是因为与我的示例相比,我看不出您的答案长度有任何原因) 您的方法在 IE7 中不起作用。我也先尝试过。问题是它对滚动事件的反应不够快。它让文档滚动,然后当您的 JS 将滚动位置重置回您想要的位置时将其捕捉回来。 另外,如果 body 溢出了auto
以外的任何内容,它将被覆盖。我需要保留现有设置,这样也会增加一些开销。
有谁知道为什么简单地用overflow: hidden
设计html
和body
是不够的?我们最终仍然需要事件处理程序。
这是一个绝妙的答案。要使其在触摸设备上运行,请查看this 答案。【参考方案2】:
这可能会或可能不会满足您的目的,但您可以扩展 jScrollPane 以在其滚动之前触发其他功能。我只是对此进行了一点测试,但我可以确认您可以跳进去并完全阻止滚动。我所做的只是:
下载演示压缩包:http://github.com/vitch/jScrollPane/archives/master 打开“事件”演示 (events.html) 编辑它以使用非缩小脚本源:<script type="text/javascript" src="script/jquery.jscrollpane.js"></script>
在 jquery.jscrollpane.js 中,插入一个“return;”在第 666 行(吉祥的行号!但如果您的版本略有不同,这是positionDragY(destY, animate)
函数的第一行
启动 events.html,您会看到一个正常滚动的框,由于您的编码干预,它不会滚动。
您可以通过这种方式控制整个浏览器的滚动条(参见 fullpage_scroll.html)。
因此,大概下一步是添加对某个其他函数的调用,该函数会触发并执行您的锚定魔法,然后决定是否继续滚动。您还可以调用 API 来设置 scrollTop 和 scrollLeft。
如果您需要更多帮助,请在您所了解的地方发帖!
希望这有帮助。
【讨论】:
【参考方案3】:你不能把身体高度设置为 100% 并隐藏溢出吗?见http://jsbin.com/ikuma4/13/edit
【讨论】:
$("html").css( height: '100%', overflow: 'hidden' );它很有效,谢谢阿德里安【参考方案4】:我在这里提出了一个可能有帮助的答案: jQuery simplemodal disable scrolling
它展示了如何在不移动文本的情况下关闭滚动条。关于simplemodal的部分可以忽略。
【讨论】:
【参考方案5】:您可以使用此代码:
$("body").css("overflow", "hidden");
【讨论】:
您仍然可以使用鼠标中键滚动。 不,这没关系,没有滚动! 如果您使用一些额外的 css,您可以完全禁用滚动,请参阅我的回答了解更多详细信息。【参考方案6】:您可以使用可滚动的 div 覆盖窗口,以防止滚动页面上的内容。 而且,通过隐藏和显示,您可以锁定/解锁您的滚动条。
做这样的事情:
#scrollLock
width: 100%;
height: 100%;
position: fixed;
overflow: scroll;
opacity: 0;
display:none
#scrollLock > div
height: 99999px;
function scrollLock()
$('#scrollLock').scrollTop('10000').show();
function scrollUnlock()
$('#scrollLock').hide();
【讨论】:
请不要使用“u”和“smth”之类的缩写。花点时间正确拼写,以提高可读性。【参考方案7】:我只是对tfe 的解决方案进行了一些调整。特别是,我添加了一些额外的控件,以确保当滚动条设置为 hidden
时,页面内容不会移动(又名 page shift)。
可以分别定义两个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>
没有初始边距。
请注意,虽然上述解决方案在大多数实际情况下都有效,但它并不确定,因为它需要对页面进行一些进一步的定制,例如包含position:fixed
的标题。让我们用一个例子来讨论这个特殊情况。假设有
<body>
<div id="header">My fixedheader</div>
<!--- OTHER CONTENT -->
</body>
与
#headerposition: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);
最后,注意一些可能的边距或填充的初始值。
【讨论】:
你的 javascript 中有错误 $body.css('margin-right': 0, 'margin-bottom', 0);应该是 $body.css('margin-right': 0, 'margin-bottom': 0); 其实只要用marginRight
和marginLeft
:)【参考方案8】:
对于有居中布局的人(通过margin:0 auto;
),这里是position:fixed
解决方案与@tfe 提出的解决方案的混搭。
如果您遇到页面对齐问题(由于滚动条显示/隐藏),请使用此解决方案。
// lock scroll position, but retain settings for later
var scrollPosition = [
window.pageXOffset || document.documentElement.scrollLeft || document.body.scrollLeft,
window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop
];
var $html = $('html'); // bow to the demon known as MSIE(v7)
$html.addClass('modal-noscroll');
$html.data('scroll-position', scrollPosition);
$html.data('margin-top', $html.css('margin-top'));
$html.css('margin-top', -1 * scrollPosition[1]);
…结合…
// un-lock scroll position
var $html = $('html').removeClass('modal-noscroll');
var scrollPosition = $html.data('scroll-position');
var marginTop = $html.data('margin-top');
$html.css('margin-top', marginTop);
window.scrollTo(scrollPosition[0], scrollPosition[1])
…最后,.modal-noscroll
的 CSS…
.modal-noscroll
position: fixed;
overflow-y: scroll;
width: 100%;
我敢说这比任何其他解决方案都更合适,但我还没有彻底测试它那个......:P
编辑:请注意,我不知道这会在触摸设备上执行多糟糕(阅读:炸毁)。
【讨论】:
【参考方案9】:这将完全禁用滚动:
$('html, body').css(
overflow: 'hidden',
height: '100%'
);
恢复:
$('html, body').css(
overflow: 'auto',
height: 'auto'
);
在 Firefox 和 Chrome 上测试过。
【讨论】:
仍然在 chrome 上使用鼠标中键滚动。 这会丢失当前的滚动位置。 OP 明确提到了捕获滚动位置,所以我认为他需要这样做。无论如何,我需要它,所以这对我来说用处有限 PS 省略height: 100%
可以有效地将滚动锁定在当前位置而不会跳转 - 至少在最新的 Chrome 上是这样。
这不是正确的答案。滚动位置未被捕获
像魅力一样工作。这只是提醒'html'和'body'同样重要。【参考方案10】:
我编写了一个 jQuery 插件来处理这个问题:$.disablescroll。
它可以防止从鼠标滚轮、触摸移动和按键事件中滚动,例如 Page Down。
有一个demo here。
用法:
$(window).disablescroll();
// To re-enable scrolling:
$(window).disablescroll("undo");
【讨论】:
我尝试使用您的 disablescroll() 插件在听到 mouswheel/scroll 事件时暂时禁用滚动,但它不起作用。你有没有机会知道实现这种效果的方法? @J.B.我可能可以提供帮助,但 cmets 不是最好的地方。加入我的堆栈溢出聊天,我会看看我能做什么:chat.***.com/rooms/55043/disablescroll-usage 很抱歉,这个插件甚至在你的 jsfiddle 中都不起作用。 您可以告诉我它在哪个浏览器/平台上似乎无法运行,来帮助我检查一下?【参考方案11】:您也可以使用 DOM 来执行此操作。假设你有一个这样调用的函数:
function disable_scroll()
document.body.style.overflow="hidden";
仅此而已!希望这对所有其他答案有所帮助!
【讨论】:
【参考方案12】:试试这个
$('#element').on('scroll touchmove mousewheel', function(e)
e.preventDefault();
e.stopPropagation();
return false;
)
【讨论】:
正是我想要的……几乎。无论如何要在箭头键期间禁用它? @Cody - 将此与 css 溢出结合起来:隐藏 @cubbiu 怎么反转? 你可以使用$('#element').off('scroll touchmove mousewheel');
很好的解决方案。虽然您如何只禁用 body
滚动但允许在具有 overflow: scroll
的其他子元素中滚动?【参考方案13】:
这就是我最终做的:
CoffeeScript:
$("input").focus ->
$("html, body").css "overflow-y","hidden"
$(document).on "scroll.stopped touchmove.stopped mousewheel.stopped", (event) ->
event.preventDefault()
$("input").blur ->
$("html, body").css "overflow-y","auto"
$(document).off "scroll.stopped touchmove.stopped mousewheel.stopped"
Javascript:
$("input").focus(function()
$("html, body").css("overflow-y", "hidden");
$(document).on("scroll.stopped touchmove.stopped mousewheel.stopped", function(event)
return event.preventDefault();
);
);
$("input").blur(function()
$("html, body").css("overflow-y", "auto");
$(document).off("scroll.stopped touchmove.stopped mousewheel.stopped");
);
【讨论】:
【参考方案14】:不确定是否有人尝试过我的解决方案。这适用于整个 body/html,但毫无疑问它可以应用于任何触发滚动事件的元素。
只需根据需要设置和取消设置 scrollLock。
var scrollLock = false;
var scrollMem = left: 0, top: 0;
$(window).scroll(function()
if (scrollLock)
window.scrollTo(scrollMem.left, scrollMem.top);
else
scrollMem =
left: self.pageXOffset || document.documentElement.scrollLeft || document.body.scrollLeft,
top: self.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop
;
);
这是JSFiddle的例子
希望这个对某人有所帮助。
【讨论】:
这个可以正常工作,但有一个例外。当滚动被锁定时,我滚动,它有点抽搐,然后才真正锁定滚动......【参考方案15】:要关闭滚动试试这个:
var current = $(window).scrollTop();
$(window).scroll(function()
$(window).scrollTop(current);
);
重置:
$(window).off('scroll');
【讨论】:
@EveryScreamer 不,它会让屏幕像疯了一样摇晃。试图找到解决方法。【参考方案16】:一个用于禁用滚动的衬里,包括鼠标中键。
$(document).scroll(function () $(document).scrollTop(0); );
edit:无论如何都不需要jQuery,下面与vanilla JS中的相同(这意味着没有框架,只有JavaScript):
document.addEventListener('scroll', function () this.documentElement.scrollTop = 0; this.body.scrollTop = 0; )
this.documentElement.scrollTop - 标准
this.body.scrollTop - IE 兼容性
【讨论】:
【参考方案17】:如果您只想禁用键盘导航滚动,您可以覆盖 keydown 事件。
$(document).on('keydown', function(e)
e.preventDefault();
e.stopPropagation();
);
【讨论】:
【参考方案18】:有人贴了这段代码,有恢复时不保留滚动位置的问题。原因是人们倾向于将它应用于 html 和 body 或只是 body 但它应该只应用于 html。这样在恢复滚动位置时将保持:
$('html').css(
'overflow': 'hidden',
'height': '100%'
);
恢复:
$('html').css(
'overflow': 'auto',
'height': 'auto'
);
【讨论】:
不是'overflow': 'auto',
使用'overflow': 'initial',
@evtuhovdo 这就是我所缺少的。谢谢【参考方案19】:
您可以将函数附加到滚动事件并阻止其默认行为。
var $window = $(window);
$window.on("mousewheel DOMMouseScroll", onMouseWheel);
function onMouseWheel(e)
e.preventDefault();
https://jsfiddle.net/22cLw9em/
【讨论】:
它有效。只需要发布的重置代码匹配Patricks answer【参考方案20】:试试这个代码:
$(function()
// ...
var $body = $(document);
$body.bind('scroll', function()
if ($body.scrollLeft() !== 0)
$body.scrollLeft(0);
);
// ...
);
【讨论】:
【参考方案21】: 隐藏卷轴:$("body").css("overflow", "hidden");
恢复卷轴:$("body").css("overflow", "initial");
【讨论】:
【参考方案22】:我认为最好和干净的解决方案是:
window.addEventListener('scroll',() =>
var x = window.scrollX;
var y = window.scrollY;
window.scrollTo(x,y);
);
使用 jQuery:
$(window).on('scroll',() =>
var x = window.scrollX;
var y = window.scrollY;
window.scrollTo(x,y)
)
那些事件监听器应该阻止滚动。 只需删除它们即可重新启用滚动
【讨论】:
【参考方案23】:我正在使用以下代码来禁用滚动,它工作正常
$('html').css(
'overflow': 'hidden',
'height': '100%'
);
除了在我的 android 平板电脑上,url 地址栏和顶部窗口标签仍然可见,当用户上下滚动时,窗口也会上下滚动大约 40px,并显示/隐藏 url 栏和标签。 有没有办法防止这种情况并完全禁用滚动?
【讨论】:
【参考方案24】:如果想以编程方式禁用滚动,您可以使用:
overflow: clip;
如果您想为用户禁用滚动,您可以使用:
overflow: hidden;
https://developer.mozilla.org/en-US/docs/Web/CSS/overflow
overflow 属性的浏览器支持各不相同:
https://caniuse.com/?search=overflow
【讨论】:
以上是关于如何使用 jQuery 以编程方式禁用页面滚动的主要内容,如果未能解决你的问题,请参考以下文章
是否可以为特定的 jQuery Ajax 调用禁用 Turbolinks 以防止页面刷新和滚动?
Objective-C:如何在 UIScrollView 中禁用垂直滚动
如何使用 Objective-C 以编程方式使我的 UIView 可水平滚动?