如何暂时禁用滚动?


434

我使用的是scrollTo jQuery插件,想知道是否可以通过Java临时禁用window元素上的滚动吗?我要禁用滚动的原因是,当您在scrollTo设置动画时滚动时,它真的很难看;)

当然,我可以做一个$("body").css("overflow", "hidden");,然后在动画停止时将其放回自动,但是如果滚动条仍然可见但不活动,那会更好。


12
如果仍在显示,则培训用户以使其必须起作用。如果剂量没有移动或没有响应,那么它将破坏用户关于页面工作方式的思维模式,并导致混乱。我只会找到一种更好的方式来处理动画时的滚动,例如停止动画。
Marcus Whybrow

Answers:


730

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台式机和现代移动浏览器


114
困在此陷阱中的其他开发人员的提示:确保确保从其他jQuery尝试停止滚动的操作中删除所有“ e.stopPropagation()”调用,因为这不仅不起作用,而且还防止事件冒泡至此代码确实有效。希望我浪费的30分钟会帮助您节省其他时间:)
Dirk van Bergen 2013年

4
您可以在禁用的键数组中添加32(空格)(在代码注释中显示)。
gblazex 2013年

14
我可以像往常一样滚动它:使用中键按下并移动鼠标...因此,该技巧不会像我这样的用户受到影响;)
Denis V

11
滚动条未禁用。
verism 2014年

8
这在Chrome上不再适用
PerrierCitror

427

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

.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')

4
得到它了!您必须像处理一样处理touchmove事件$('body').bind('touchmove', function(e){e.preventDefault()})。编辑了此答案以包括此移动解决方案。
MusikAnimal 2012年

3
太酷了,只需确保任何内部滚动都可以在触摸设备的模式下使用。可以在模态下方进行覆盖,并防止在覆盖层而不是主体上使用默认的touchmove。
hallodom

63
尽管此解决方案确实有效,但它具有滚动回页面顶部的(潜在)不良影响。
Matt

3
除非我的选择者是我,否则这对我不起作用$('body,html')
PickYourPoison 2014年

22
此解决方案有效,但是当您将此类应用于身体时(例如,在窗口os下),滚动条消失并创建“碰撞”效果
Georgio 2014年

57

这是一种非常基本的方法:

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

在IE6中有点跳动。


14
并不是真正的禁用,更像是尝试滚动时的默认设置。
Marcus Whybrow

11
@Marcus和一个不可取消的事件一样好。
sdleihssirhc 2011年

3
即使它并没有真正禁用它,它也会对其进行仿真,这对我来说已经足够了。
克里斯·比尔

11
恕我直言-最好的答案在这里。另外,您不必将其锁定为(0, 0),只需使用当前滚动位置即可。
YemSalat 2015年

4
但是我们如何重新启用它?
控制论

41

以下解决方案是基本但纯JavaScript(无jQuery)的解决方案:

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

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

3
Safari 7.1和IE 11中的Jumpy。最新的Chrome,Firefox,Opera可以。
TimoKähkönen2014年

还是一点点神经质的最新铬
贾森Allshorn

做工精细,在Safari,Chrome浏览器,但闪烁在IE浏览器
Bhuvan阿罗拉

如果此解决方案不适用于某些浏览器,则说明浏览器存在问题
Oto Shavadze

正如在另一个答案中提到的scroll-behavior: smooth那样。另外,我不同意Oto的说法,这是浏览器的错误。您基本上是假设某些事情在现实中是异步时会立即发生
Matt Fletcher

25

该解决方案将在禁用滚动功能时保持当前滚动位置,这与某些将用户跳回顶部的方式不同。

它基于galambalazs的answer,但支持触摸设备,并使用jquery插件包装器重构为单个对象。

演示在这里。

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

很高兴这很有用。注意:我已经编辑了jQuery插件格式链接
乔什·哈里森

如果禁用滚动按钮确实起作用,可能会有所帮助
cameronjonesweb 2014年

@ user1672694,它可以在Chrome中运行。您在什么浏览器上以及在哪个演示页上发现了此错误?控制台中是否存在JS错误?
2014年

在Chrome(38,Windows 7)上,我仍然可以通过单击并按住中间按钮然后拖动来滚动。
塞西2014年

1
请忽略,我发现绑定它很有mousewheel魅力
adamj

17

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

对于此问题,有很多解决方法仍可以显示滚动条,例如为容器提供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;

这显示了一个灰色的滚动条,希望对将来的访问者有帮助。


8

我一直在寻找解决此问题的方法,但对上述任何一种方法都不满意(在撰写此答案时),所以我想出了这个方法。

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

我发现这个工作对我来说,如果我说overflow-y: scroll.scrollDisabled风格。否则,每次滚动条都隐藏时会有一点跳跃。当然,这仅对我有用,因为我的页面足够长,即使在最大的显示器上也需要滚动条。
Andrew Miner

7

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

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

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

3
您确定这是一个答案,而不仅仅是对其他答案的评论?
IvanH 2013年

6

从Chrome 56和其他现代浏览器开始,您必须添加passive:falseaddEventListener通话中才能preventDefault正常工作。所以我用它来停止在手机上滚动:

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

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

5

不,我不会进行事件处理,因为:

  • 并非所有事件都能保证顺利进行,

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

  • 如果在事件分离阶段某事出了错,那么您注定要失败。

我已经通过在隐藏的textarea上执行复制粘贴操作来猜中了,然后猜测是什么,每当我进行复制时页面就会滚动,因为在内部必须在调用之前选择textarea document.execCommand('copy')

无论如何,请注意setTimeout()

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

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


4

根据您要使用移除的滚动条实现的功能,您可以修复要从中移除滚动条的元素(单击时,或要暂时停用滚动条的其他任何触发器)

我一直在寻找“临时无滚动”解决方案,而对于我的需求,这解决了它

上课

.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 left值来轻松完成此操作

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

4

另一个解决方案:

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测试。


这对我有用,并且在使用position:fixed后滚动到顶部的问题。感谢你!
安妮·马丁内斯

3

这个怎么样?(如果您使用的是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() });
    }
};

有点跳动,但这适用于IE 7(客户端使用它)。其他解决方案则没有。
niki b 2014年

3

我正在使用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();
});

这在React不存在jQuery且React无权管理body标签状态的React中为我工作。
2016年

3

我认为取消事件的方法是公认的答案:/

相反,我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%
  • 高度,同上
  • 滚动条,固定设置位置后,页面内容不再具有滚动条,即使它在导致水平页面跳转之前具有滚动条
  • pagejump,当固定设置位置时,页面scrollTop不再有效,导致垂直页面跳转

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


3
var winX = null, 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;
};

1
这是最好的解决方案。
jfunk

@jfunk同意,简单明了,小代码,完美。谢谢
Florent Roques

2

我有同样的问题,下面是我的处理方式。

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

希望有帮助。


1

以夏安·福布斯(Cheyenne Forbes)的答案为基础,而我通过fcalderan在这里找到了一个答案:仅禁用滚动而不隐藏它? 并修复Hallodom滚动条消失的问题

CSS:

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

JS:

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

这段代码确实将您带到了页面顶部,但是我认为fcalderan的代码具有解决方法。


1

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

我的问题非常相似,几乎完全相同,唯一的区别是我不必真正显示滚动条-我只需要确保仍然使用其宽度,因此在显示覆盖图时页面的宽度不会改变。

当我开始将叠加层滑入屏幕时,我会执行以下操作:

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

在将覆盖层滑出屏幕后,我会执行以下操作:

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

重要提示:本作品完美,因为我的叠加定位absoluteright: 0pxvisible


1

最简单的方法是:

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

要撤消它:

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

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

  • 如果页面居中(水平),则页面会向左跳一点。

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


1
这将重置滚动位置
Angel David Calderaro Pacciott

@AngelDavidCalderaroPacciott不,滚动位置将保持相同的高度/距离。
大安

@Daan确实重置了Chrome上的滚动位置
汤姆

@Tom我只是检查过它,它仅在某些情况下会执行此操作(当身高与孩子的身高无关时)。请尝试更改bodyhtml代替。
大安

我敢打赌,你没有检查在iPhone的原因您的解决方案overflow:hidden在那里不起作用
Shuvo

1

这是我停止滚动的解决方案(没有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,以补偿滚动条的消失。但这也有问题,主要是针对移动浏览器。根据此方法获得钢筋宽度来解决。

一起在这支笔。



1

这是我到目前为止获得的最简单的解决方案。相信我,我尝试了所有其他方法,这是最简单的方法。它在Windows设备上效果很好,可将页面从右侧推入以为系统滚动条和IOS设备留出空间,这些设备在浏览器中不需要滚动条。因此,通过使用此方法,您将不需要在右侧添加填充,因此当您使用CSS隐藏主体或html的溢出时,页面不会闪烁

如果您考虑一下,该解决方案将非常简单。这个想法是在打开弹出窗口时为window.scrollTop()提供相同的精确位置。当窗口调整大小时,也要更改该位置(因为滚动位置一旦发生变化就更改)。

所以我们开始...

首先让我们创建一个变量,该变量将使您知道弹出窗口已打开,并将其称为stopWindowScroll。如果我们不这样做,那么您会在页面上收到未定义变量的错误,并将其设置为0-未激活。

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

现在让打开的弹出窗口功能成为您代码中任何触发您用作插件或自定义弹出窗口的函数。在这种情况下,它将是一个简单的自定义弹出窗口,并带有单击功能的简单文档。

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

因此,我们接下来要做的就是创建关闭弹出窗口功能,我再说一遍,它可以是您已经创建或正在插件中使用的任何函数。重要的是,我们需要这两个函数将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);
});

然后让我们创建window.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小提琴示例

让我知道是否有帮助。问候。


1

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

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

1

此代码将在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
  }
}

1

为了防止跳跃,这就是我使用的

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

0

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

禁用滚动:

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

关闭弹出窗口后,滚动:

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

这似乎只能停止触摸滚动,但是鼠标滚动,箭头键,页面上移和下移键等仍将起作用。-1
markasoftware

这些“事件”用于触摸滚动,只需替换您需要的任何事件即可。
pennstump

1
同样,这似乎是在其他一些非常特殊的情况下使用的。popupbeforeposition?那应该是为了什么?这与暂时禁用滚动功能有什么关系?至少使其与这种情况相关。您似乎直接从网站复制了此内容。
markasoftware

0

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

0

当尝试使用jquery的animate命令对div进行动画处理时,我在移动屏幕上遇到了类似的动画问题,但在笔记本电脑上却没有。因此,我决定使用计时器来恢复窗口的滚动位置,以至于肉眼看不见文档是静态的。此解决方案在像Samsung 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() {};
});

0

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

基于此提琴: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');
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.