我正在使用scrollTo jQuery插件,想知道是否有可能通过Javascript暂时禁用窗口元素上的滚动?我想禁用滚动的原因是,当你滚动而scrollTo是动画,它变得非常难看;)

当然,我可以做$("body").css("overflow", "hidden");然后当动画停止时把它放回自动,但如果滚动条仍然可见但不活跃会更好。


当前回答

基于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的代码有一个解决方案。

其他回答

使用Javascript函数切换overflowY,同时切换移动菜单的可见性。比如这个:

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

在打开和关闭移动菜单时调用该函数。 最好的用例是当你的移动菜单是完全视口区域。

最简单的方法是:

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

要撤消它:

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

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

如果页面是居中对齐的(水平),它会向左跳一点。

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

对我来说,这并没有带来任何内容跳跃。

禁用滚动:

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

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

(工作演示)

// 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桌面和现代移动浏览器被动监听器

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

我的问题非常相似,几乎相同,唯一的区别是我不需要实际显示滚动条-我只需要确保它的宽度仍然被使用,所以当我的覆盖显示时,页面的宽度不会改变。

当我开始滑动覆盖到屏幕,我做:

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

在我将覆盖层从屏幕上滑动后,我这样做:

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

重要:这是完美的工作,因为我的叠加是绝对定位,对:0px时可见。