如何以编程方式禁用jQuery页面滚动


163

使用jQuery,我想禁用主体的滚动:

我的想法是:

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

有没有更好的办法?


更新:

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

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

请不要提出这个建议,因为我还有其他原因。


7
“有没有更好的办法?” -除了让浏览器正常运行外?
Fenton

22
“戏剧性地”?
Mike Weller 2010年

6
也许是程序上的意思?由于这是Firefox的“以编程方式”顶部拼写更正的建议
Michael Shimmins 2010年

4
此线程正在进行\ b \
Cipi 2010年

3
@Sohnee禁止滚动!==不好
Mansiemans'2

Answers:


136

我发现执行此操作的唯一方法与您所描述的类似:

  1. 抓住当前滚动位置(不要忘记水平轴!)。
  2. 将溢出设置为隐藏(可能要保留以前的溢出值)。
  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
请访问jsbin.com/ikuma4/2/edit并向我解释您的更好的任何理由?我是否错过了某些内容(我问,因为与我的示例相比,我看不到您回答的长度有任何原因)
Hailwood 2010年

3
您的方法在IE7中不起作用。我也尝试过 问题在于它对滚动事件的反应不够快。它允许文档滚动,然后在JS将滚动位置重置回所需位置时将其对齐。
tfe 2010年

1
另外,如果body溢出了以外的东西auto,它将被覆盖。我需要保留现有设置,这样也增加了一些开销。
tfe 2010年

有谁知道为什么简单的造型htmlbody搭配overflow: hidden不够?我们仍然最终需要事件处理程序。
kpozin

4
这是一个了不起的答案。要使其在触摸设备上运行,请查看答案。
帕特里克

235

这将完全禁用滚动:

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

恢复:

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

在Firefox和Chrome上进行了测试。


18
可以正常工作。谢谢!这应该是公认的答案!
Dave Chen

6
在chrome上仍可使用鼠标中键滚动。
Lothar 2013年

16
这将丢失当前的滚动位置。OP明确提到捕获滚动位置,因此我认为他需要这样做。无论如何,我都需要它,所以这对我来说用途有限
zerm

7
PS省略height: 100%有效地将滚动锁定在当前位置而不会跳转-至少在最新的Chrome上。
zerm 2013年

2
这不是正确的答案。滚动位置没有拍摄
taylorcressy

43

试试这个

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

就是我一直在寻找的东西... 无论如何要在箭头键期间禁用它?
科迪2014年

2
@Cody-将其与CSS溢出结合在一起:隐藏
Darius.V 2014年

2
@cubbiu如何扭转呢?
Meer 2014年

3
您可以使用$('#element').off('scroll touchmove mousewheel');
arnuschky 2014年

1
很好的解决方案。尽管您将如何仅禁用body滚动,而又允许在具有子元素的其他子元素中滚动overflow: scroll
Fizzix '16

27

我只是通过tfe对解决方案进行了一些调整。特别是,我添加了一些其他控件,以确保在滚动条设置为时,页面内容不会发生移位(aka 页面移位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>没有初始保证金。

请注意,尽管上述解决方案在大多数实际情况下都可以使用,但由于它需要对页面进行一些进一步的自定义(例如,带有的标头),因此尚不确定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});
Johansrk

实际上,只需使用marginRightmarginLeft:)
Martijn

25

您可以使用以下代码:

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

8
您仍然可以使用鼠标中键滚动。
罗杰·法尔2012年

2
不,这还可以,没有任何滚动!
2013年

如果您使用一些额外的CSS,则可以完全禁用滚动,请参阅我的答案以获取更多详细信息。
gitaarik 2013年

21

要关闭滚动,请尝试以下操作:

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

重置:

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

对于我所需要的来说,这是一个绝佳的解决方案。
特里·卡特

@EveryScreamer不,它会使屏幕像疯了似的摇动。试图找到一种解决方法。
Telarian

5

我已经编写了一个jQuery插件来处理此问题:$ .disablescroll

它防止滚动鼠标滚轮,触摸移动和按键事件,例如Page Down

这里有一个演示

用法:

$(window).disablescroll();

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

我尝试使用您的disablescroll()插件在听到mouswheel / scroll事件时暂时禁用滚动,但是它不起作用。您是否知道实现此效果的方法?
黄圣人

@JB我可以帮忙,但评论不是最好的地方。和我一起参加这个堆栈溢出聊天,我将看到我能做什么:chat.stackoverflow.com/rooms/55043/disablescroll-usage
Josh Harrison

抱歉,这个插件甚至无法在您的jsfiddle中使用。
markj 2014年

您可以通过告诉我它似乎无法在哪个浏览器/平台上工作来帮助我进行检查?
乔什·哈里森


4

一个衬里可禁用滚动,包括鼠标中键。

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

编辑:无论如何都不需要jQuery,下面与香草JS中的上面相同(这意味着没有框架,只有JavaScript):

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

this.documentElement.scrollTop-标准

this.body.scrollTop-IE兼容性




3

有人发布了此代码,该代码存在恢复时不保留滚动位置的问题。原因是人们倾向于将其应用于html和body或仅应用于body,但应仅将其应用于html。这样,在恢复滚动位置时将保持:

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

恢复:

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

'overflow': 'auto',使用'overflow': 'initial',
evtuhovdo

2

这可能无法实现您的目的,但是您可以扩展jScrollPane以在滚动之前触发其他功能。我只测试了一下,但可以确认您可以进入并完全阻止滚动。我所做的就是:

  • 下载演示zip: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。

如果您需要更多帮助,请发布您的建议!

希望这有所帮助。



1

如果只想使用键盘导航禁用滚动,则可以覆盖keydown事件。

$(document).on('keydown', function(e){
    e.preventDefault();
    e.stopPropagation();
});

1

试试这个代码:

    $(function() { 
        // ...

        var $body = $(document);
        $body.bind('scroll', function() {
            if ($body.scrollLeft() !== 0) {
                $body.scrollLeft(0);
            }
        });

        // ...
    });

0

您可以使用可滚动的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();
}

7
请不要使用“ u”和“ smth”之类的缩写。为了便于阅读,请花点时间正确拼写。
Tin Man

0

对于布局居中(通过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


编辑:请注意,我不知道这可能会在触摸设备上执行(读取:爆炸)的效果。


0

您也可以使用DOM来做到这一点。假设您有一个这样调用的函数:

function disable_scroll() {
document.body.style.overflow="hidden";
}

这就是全部!希望这对所有其他答案都有所帮助!


0

这就是我最终要做的事情:

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

0

不知道是否有人尝试过我的解决方案。这适用于整个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

希望这个可以帮助到别人。


除了一个例外,这一功能可以正常工作。当滚动被锁定并且我滚动时,在实际锁定滚动之前,它有点抽搐了……
Thomas Teilmann

0

我认为最佳和干净的解决方案是:

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

那些事件侦听器应阻止滚动。只需删除它们即可重新启用滚动

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.