如何暂时禁用滚动?

时间:2011-01-22 19:23:44

标签: javascript jquery scroll

我正在使用scrollTo jQuery插件,想知道是否可以通过Javascript临时禁用滚动窗口元素?我想禁用滚动的原因是当你滚动时滚动动画,它会变得非常丑陋;)

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

43 个答案:

答案 0 :(得分:671)

scroll事件无法取消。但你可以通过取消这些互动事件来实现:
与滚动相关联的鼠标 & 触摸滚动按钮

[Working demo]

// 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 = e || window.event;
  if (e.preventDefault)
      e.preventDefault();
  e.returnValue = false;  
}

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

function disableScroll() {
  if (window.addEventListener) // older FF
      window.addEventListener('DOMMouseScroll', preventDefault, false);
  document.addEventListener('wheel', preventDefault, {passive: false}); // Disable scrolling in Chrome
  window.onwheel = preventDefault; // modern standard
  window.onmousewheel = document.onmousewheel = preventDefault; // older browsers, IE
  window.ontouchmove  = preventDefault; // mobile
  document.onkeydown  = preventDefaultForScrollKeys;
}

function enableScroll() {
    if (window.removeEventListener)
        window.removeEventListener('DOMMouseScroll', preventDefault, false);
    document.removeEventListener('wheel', preventDefault, {passive: false}); // Enable scrolling in Chrome
    window.onmousewheel = document.onmousewheel = null; 
    window.onwheel = null; 
    window.ontouchmove = null;  
    document.onkeydown = null;  
}

修改

添加document.addEventListener('wheel', preventDefault, {passive: false});以确保该功能仍可在Chrome上使用。

答案 1 :(得分:398)

只需向身体添加一个类:

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

答案 2 :(得分:51)

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

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

这在IE6中是一种跳跃。

答案 3 :(得分:30)

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

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

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

答案 4 :(得分:24)

此解决方案将保持当前滚动位置,同时禁用滚动,这与将用户跳回到顶部的一些不同。

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

Demo here.

<强> On github here.

/**
 * $.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);

答案 5 :(得分:14)

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

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

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

答案 6 :(得分: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);
}

答案 7 :(得分:7)

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

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

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

答案 8 :(得分: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进行测试。

答案 9 :(得分: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() });
    }
};

答案 10 :(得分:3)

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

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

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

答案 11 :(得分:3)

根据您要删除的滚动要实现的内容,您可以修复要删除滚动的元素(在点击时,或者您想要暂时停用滚动的其他任何触发器)

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

上课

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

答案 12 :(得分: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();
});

答案 13 :(得分:2)

在我看来,取消接受的答案中的事件是一种可怕的方法:/

相反,我使用了下面的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": ""});
    }
}

此代码考虑了宽度,高度,滚动条和pagejump问题。

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

  • 宽度,当设置位置固定时,html元素宽度可以小于100%
  • 身高,与上述相同
  • 滚动条,当设置位置固定时,页面内容不再有滚动条,即使它有一个滚动条也导致水平的pagejump
  • pagejump,当设置位置固定时,页面scrollTop不再有效导致垂直pagejump

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

答案 14 :(得分:2)

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

  • 并非所有事件都能保证达到目标,

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

  • 如果在事件分离阶段出现问题,那您就注定了。

我已经通过在隐藏的文本区域执行复制粘贴操作来猜测这一点,并猜测是什么,每当我进行复制时页面就会滚动,因为在内部,我必须先选择文本区域,然后才能致电document.execCommand('copy')

无论如何,我要注意setTimeout()

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

动量闪烁存在,因为滚动条会暂时消失,但是我可以接受。

答案 15 :(得分:1)

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

答案 16 :(得分:1)

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

public List<CustomerLocation> getCustomersPlacesIndexWithinLocation(GenericRequest genericRequest) {
    GeoDistanceQueryBuilder geoDistanceQueryBuilder = QueryBuilders
            .geoDistanceQuery("geoPoint")
            .point(genericRequest.getLatitude(),genericRequest.getLongitude())
            .distance(10, DistanceUnit.KILOMETERS);

    List<CustomerLocation> customerLocationList;

    if(genericRequest.getUserId()!=null) {
        customerLocationList = customerLocationRepository.findByCifNoAndUserIdOrderByLastSeenDateDesc(Integer.valueOf(genericRequest.getClientNo()),genericRequest.getUserId());
    } else {
        customerLocationList = customerLocationRepository.findByCifNoAndUserIdIsNullOrderByLastSeenDateDesc(Integer.valueOf(genericRequest.getClientNo()));
    }

    SearchQuery searchQuery = new NativeSearchQueryBuilder()
            .withFilter(geoDistanceQueryBuilder)
            .build();

    return elasticsearchTemplate.queryForList(searchQuery,CustomerLocation.class);
}

和我的CSS

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

答案 17 :(得分:1)

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

我的问题非常相似,几乎完全相同,唯一的区别是我没有必要真正显示滚动条 - 我只需要确保它的宽度仍然会被使用,所以页面是&#39; s显示我的叠加层时宽度不会改变。

当我开始将叠加层滑入屏幕时,我会这样做:

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

在我从屏幕上滑下我的叠加后,我做了:

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

重要事项这非常有效,因为absolute时我的叠加层位于right: 0pxvisible

答案 18 :(得分:1)

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

.no-scroll{
  overflow: hidden;
}

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

然后在您想停止滚动事件时调用该函数或...

答案 19 :(得分: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的填充权限放在右边以补偿滚动条的消失。但这也存在问题,主要是针对移动浏览器。通过根据this得到条宽来解决。

All together in this Pen.

答案 20 :(得分:1)

以Cheyenne Forbes的回答为基础,我在这里通过fcalderan找到答案:Just disable scroll not hide it? 并修复Hallodom的滚动条问题消失

CSS:

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

JS:

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

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

答案 21 :(得分:1)

最简单的方法是:

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

撤消它:

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

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

  • 如果页面中心对齐(水平),页面将向左跳跃一点。

这是因为滚动条被移除,视口变得更宽。

答案 22 :(得分:1)

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

/* 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;
}
希望这有帮助。

答案 23 :(得分:0)

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

答案 24 :(得分:0)

这是我到目前为止获得的最简单的解决方案。相信我,我尝试了所有其他方法,这是最简单的方法。 在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 Fiddle Example

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

答案 25 :(得分:0)

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

这比长代码更好。容易理解

答案 26 :(得分:0)

我在这篇文章中找到了解决方案。就我而言,我希望在

内水平滚动时取消垂直滚动

喜欢这个=>

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

答案 27 :(得分:0)

我继承的网站,滚动显示了链接。要在临时单击特定按钮时禁用此滚动,这对我有用:

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

答案 28 :(得分:0)

有两个 button 并且它们有 onclick 函数。 HTML 如下所示:

<button onclick='enableScroll()'> Enable </button>
<button onclick='disableScroll()'> Disable </button>

下面给出了js:

function enableScroll(){
  document.documentElement.style.position = "static";
}
function disableScroll(){
  document.documentElement.style.position = "fixed";
}

答案 29 :(得分:0)

对我来说,这没有任何内容跳转。

禁用滚动:

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

答案 30 :(得分:0)

在切换移动菜单可见性的同时使用 Javascript 功能切换 overflowY。像这样例如:

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

在您打开和关闭移动菜单时调用该函数。 最佳用例是当您的移动菜单占据整个视口区域时。

答案 31 :(得分:0)

此答案提出了一种解决方案,用于消除应用 this solution 中建议的 overflow: hidden 时发生的“颠簸”。由于编辑被拒绝,这里是:


消除应用 overflow: hidden 时发生的“凹凸”,您可以计算滚动条的宽度并将其替换为边距。以下是 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,那么获取现有元素并向其添加滚动条宽度应该不是问题。

答案 32 :(得分:0)

  

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

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

答案 33 :(得分: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);
}

您甚至可以通过此黑客禁用右键菜单:

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

答案 34 :(得分:0)

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

了解更多信息。看看这个: -

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

答案 35 :(得分:0)

我在另一个site找到了这个答案:

禁用滚动:

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

关闭弹出窗口后滚动:

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

答案 36 :(得分:0)

我刚刚放在一起的东西:

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>

答案 37 :(得分:0)

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

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

    }
});

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

答案 38 :(得分: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');

答案 39 :(得分:0)

我对此问题的看法还包括对身体宽度的关注,因为当我们使用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';
});

答案 40 :(得分:0)

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

此方法的主要逻辑:应在jquery animate命令之前启动将窗口的滚动位置设置为原始滚动位置的计时器,然后在动画完成时我们需要清除此计时器({ {1}}是动画开始前的位置。)

我惊喜地发现如果计时器间隔为original scroll position,那么文档在动画期间实际上是静态的,这正是我的目标。

1 millisecond

另一个有效的解决方案:根据Mohammad Anini在此帖子中启用/禁用滚动的答案,我还发现以下代码的修改版本有效。

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

答案 41 :(得分:-4)

我发现了一种更好但有缺陷的方法,结合了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%肯定它适用于主流浏览器。

答案 42 :(得分:-4)

使用JavaScript启用以下CSS会有所帮助。我不像其他人那么好,但这对我有用。

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