我试图禁用父母的html/身体滚动条,而我正在使用一个灯箱。这里的主要词是disable。我不想用溢出来隐藏它。

这样做的原因是overflow: hidden会使站点跳转并占用原来滚动的区域。

我想知道是否有可能禁用滚动条,同时仍然显示它。


当前回答

如果覆盖层下的页面可以“固定”在顶部,当你打开覆盖层时,你可以设置

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

将这个类提供给可滚动的主体,您仍然应该看到正确的滚动条,但内容是不可滚动的。

用jquery来保持页面的位置

$('body').css('top', - ($(window).scrollTop()) + 'px').addClass('disableScroll');

当你关闭覆盖时,只需恢复这些属性

var top = $('body').position().top;
$('body').removeClass('disableScroll').css('top', 0).scrollTop(Math.abs(top));

我之所以建议采用这种方式,只是因为您不需要更改任何滚动事件

其他回答

这是我们的解。简单地保存覆盖打开时的滚动位置,在用户试图滚动页面时滚动回保存的位置,并在覆盖关闭时关闭侦听器。

它在IE上有点不稳定,但在Firefox/Chrome上却很有魅力。

var body = $("body"), overlay = $("#overlay"), overlayShown = false, overlayScrollListener = null, overlaySavedScrollTop = 0, overlaySavedScrollLeft = 0; function showOverlay() { overlayShown = true; // Show overlay overlay.addClass("overlay-shown"); // Save scroll position overlaySavedScrollTop = body.scrollTop(); overlaySavedScrollLeft = body.scrollLeft(); // Listen for scroll event overlayScrollListener = body.scroll(function() { // Scroll back to saved position body.scrollTop(overlaySavedScrollTop); body.scrollLeft(overlaySavedScrollLeft); }); } function hideOverlay() { overlayShown = false; // Hide overlay overlay.removeClass("overlay-shown"); // Turn scroll listener off if (overlayScrollListener) { overlayScrollListener.off(); overlayScrollListener = null; } } // Click toggles overlay $(window).click(function() { if (!overlayShown) { showOverlay(); } else { hideOverlay(); } }); /* Required */ html, body { margin: 0; padding: 0; height: 100%; background: #fff; } html { overflow: hidden; } body { overflow-y: scroll; } /* Just for looks */ .spacer { height: 300%; background: orange; background: linear-gradient(#ff0, #f0f); } .overlay { position: fixed; top: 20px; bottom: 20px; left: 20px; right: 20px; z-index: -1; background: #fff; box-shadow: 0 0 5px rgba(0, 0, 0, .3); overflow: auto; } .overlay .spacer { background: linear-gradient(#88f, #0ff); } .overlay-shown { z-index: 1; } <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script> <h1>Top of page</h1> <p>Click to toggle overlay. (This is only scrollable when overlay is <em>not</em> open.)</p> <div class="spacer"></div> <h1>Bottom of page</h1> <div id="overlay" class="overlay"> <h1>Top of overlay</h1> <p>Click to toggle overlay. (Containing page is no longer scrollable, but this is.)</p> <div class="spacer"></div> <h1>Bottom of overlay</h1> </div>

我用scrollLock方法解决了这个问题,该方法为滚动轮事件和按下键事件设置侦听器,并使用preventScroll方法处理这些事件。就像这样:

preventScroll = function (e) {
    // prevent scrollwheel events
    e.preventDefault();
    e.stopPropagation();

    // prevent keydown events
    var keys = [32, 33, 34, 35, 37, 38, 39, 40];
    if (keys.includes(e.keyCode)) {
        e.preventDefault();
    }

    return false;
}

scrollLock = function (lock) {
    if (lock) {
        document.querySelector("#container").addEventListener("wheel", preventScroll);
        document.addEventListener("keydown", preventScroll);
    }
    else {
        document.querySelector("#container").removeEventListener("wheel", preventScroll);
        document.querySelector("#container").removeEventListener("keydown", preventScroll);
    }
}

粗糙但有效的方法是强制滚动回顶部,从而有效地禁用滚动:

var _stopScroll = false;
window.onload = function(event) {
    document.onscroll = function(ev) {
        if (_stopScroll) {
            document.body.scrollTop = "0px";
        }
    }
};

打开灯箱时升起旗子,关闭灯箱时降下旗子。

现场测试用例。

我有一些其他固定的元素在页面和设置主体的位置固定导致了一堆其他问题,所以我做了一个hack的方式:

const scrollbarWidth = window.innerWidth - document.documentElement.clientWidth;

// on opening modal
document.body.style.overflow = "hidden"
document.body.style.paddingRight = `${scrollbarWidth}px`

// on closing modal
document.body.style.overflow = "unset",
document.body.style.paddingRight = "0px"

这个想法是添加一个与浏览器滚动条宽度相同的右填充,以模仿假滚动条并防止内容移动。

你不能禁用滚动事件,但是你可以禁用导致滚动的相关操作,比如鼠标滚轮和touchmove:

$('body').on('mousewheel touchmove', function(e) {
      e.preventDefault();
});