Javascript 只是禁用滚动而不是隐藏它?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/8701754/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-24 07:08:49  来源:igfitidea点击:

Just disable scroll not hide it?

javascriptjqueryhtmlcss

提问by Dejan.S

I'm trying to disable the html/body scrollbar of the parent while I'm using a lightbox. The main word here is disable. I do notwant to hide it with overflow: hidden;.

我正在尝试在使用灯箱时禁用父级的 html/body 滚动条。这里的主要词是disable。我也没有想隐藏它overflow: hidden;

The reason for this is that overflow: hiddenmakes the site jump and take up the area where the scroll was.

这样做的原因是overflow: hidden使站点跳跃并占据滚动所在的区域。

I want to know if its possible to disable a scrollbar while still showing it.

我想知道是否可以在仍然显示滚动条的同时禁用它。

采纳答案by Fabrizio Calderan

If the page under the overlayer can be "fixed" at the top, when you open the overlay you can set

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

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

you should still see the right scrollbar but the content is not scrollable. When you close the overlay just revert these properties with

您仍然应该看到正确的滚动条,但内容不可滚动。当您关闭叠加层时,只需使用以下命令还原这些属性

body { position: static; overflow-y:auto }

I just proposed this way only because you wouldn't need to change any scroll event

我提出这种方式只是因为您不需要更改任何滚动事件

Update

更新

You could also do a slight improvement: if you get the document.documentElement.scrollTopproperty via javascript just before the layer opening, you could dynamically assign that value as topproperty of the body element: with this approach the page will stand in its place, no matter if you're on top or if you have already scrolled.

您还可以做一点改进:如果您document.documentElement.scrollTop在图层打开之前通过 javascript获取该属性,您可以将该值动态分配为topbody 元素的属性:使用这种方法,页面将保持原位,无论您是否“重新在顶部或者如果您已经滚动。

Css

css

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

JS

JS

$('body').css('top', -(document.documentElement.scrollTop) + 'px')
         .addClass('noscroll');

回答by Mike Garcia

Four little additions to the selected solution:

所选解决方案的四个小补充:

  1. Apply 'noscroll' to html instead of to bodyto prevent double scroll bars in IE
  2. To check if there's actually a scroll barbefore adding the 'noscroll' class. Otherwise, the site will also jump pushed by the new non-scrolling scroll bar.
  3. To keep any possible scrollTopso the entire page doesn't go back to the top (like Fabrizio's update, but you need to grab the value before adding the 'noscroll' class)
  4. Not all browsers handle scrollTop the same way as documented at http://help.dottoro.com/ljnvjiow.php
  1. 将 'noscroll' 应用于html 而不是 body以防止 IE 中的双滚动条
  2. 检查是否确实有一个滚动条增加了“noscroll”课前。否则,网站也会被新的非滚动滚动条跳转推送。
  3. 保留任何可能的scrollTop以便整个页面不会回到顶部(如 Fabrizio 的更新,但您需要在添加 'noscroll' 类之前获取该值)
  4. 并非所有浏览器都以http://help.dottoro.com/ljnvjiow.php 中记录的相同方式处理 scrollTop

Complete solution that seems to work for most browsers:

似乎适用于大多数浏览器的完整解决方案:

CSS

CSS

html.noscroll {
    position: fixed; 
    overflow-y: scroll;
    width: 100%;
}

Disable scroll

禁用滚动

if ($(document).height() > $(window).height()) {
     var scrollTop = ($('html').scrollTop()) ? $('html').scrollTop() : $('body').scrollTop(); // Works for Chrome, Firefox, IE...
     $('html').addClass('noscroll').css('top',-scrollTop);         
}

Enable scroll

启用滚动

var scrollTop = parseInt($('html').css('top'));
$('html').removeClass('noscroll');
$('html,body').scrollTop(-scrollTop);

Thanks to Fabrizio and Dejan for putting me on the right track and to Brodingo for the solution to the double scroll bar

感谢 Fabrizio 和 Dejan 让我走上正轨,感谢 Brodingo解决双滚动条

回答by ceed

With jQuery inluded:

包含 jQuery:



disable

禁用

$.fn.disableScroll = function() {
    window.oldScrollPos = $(window).scrollTop();

    $(window).on('scroll.scrolldisabler',function ( event ) {
       $(window).scrollTop( window.oldScrollPos );
       event.preventDefault();
    });
};

enable

使能够

$.fn.enableScroll = function() {
    $(window).off('scroll.scrolldisabler');
};

usage

用法

//disable
$("#selector").disableScroll();
//enable
$("#selector").enableScroll();

回答by Dejan.S

I'm the OP

我是 OP

With the help of answer from fcalderan I was able to form a solution. I leave my solution here as it brings clarity to how to use it, and adds a very crucial detail, width: 100%;

在 fcalderan 的回答的帮助下,我能够形成一个解决方案。我把我的解决方案留在这里,因为它让我清楚地知道如何使用它,并添加了一个非常关键的细节,width: 100%;

I add this class

我添加这个类

body.noscroll
{
    position: fixed; 
    overflow-y: scroll;
    width: 100%;
}

this worked for me and I was using Fancyapp.

这对我有用,我正在使用 Fancyapp。

回答by dmackenz

This worked really well for me....

这对我来说非常有效......

// disable scrolling
$('body').bind('mousewheel touchmove', lockScroll);

// enable scrolling
$('body').unbind('mousewheel touchmove', lockScroll);


// lock window scrolling
function lockScroll(e) {
    e.preventDefault();
}

just wrap those two lines of code with whatever decides when you are going to lock scrolling.

只需用决定何时锁定滚动的任何内容包装这两行代码即可。

e.g.

例如

$('button').on('click', function() {
     $('body').bind('mousewheel touchmove', lockScroll);
});

回答by tocqueville

You cannot disable the scroll event, but you can disable the related actions that lead to a scroll, like mousewheel and touchmove:

您不能禁用滚动事件,但可以禁用导致滚动的相关操作,例如鼠标滚轮和触摸移动:

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

回答by mpen

You can hide the body's scrollbar with overflow: hiddenand set a margin at the same time so that the content doesn't jump:

您可以隐藏主体的滚动条并overflow: hidden同时设置边距,以便内容不会跳转:

let marginRightPx = 0;
if(window.getComputedStyle) {
    let bodyStyle = window.getComputedStyle(document.body);
    if(bodyStyle) {
        marginRightPx = parseInt(bodyStyle.marginRight, 10);
    }
}

let scrollbarWidthPx = window.innerWidth - document.body.clientWidth;
Object.assign(document.body.style, {
    overflow: 'hidden',
    marginRight: `${marginRightPx + scrollbarWidthPx}px`
});

And then you can add a disabled scrollbar to the page to fill in the gap:

然后你可以在页面上添加一个禁用的滚动条来填补空白:

textarea {
  overflow-y: scroll;
  overflow-x: hidden;
  width: 11px;
  outline: none;
  resize: none;
  position: fixed;
  top: 0;
  right: 0;
  bottom: 0;
  border: 0;
}
<textarea></textarea>

I did exactly this for my own lightbox implementation. Seems to be working well so far.

我正是为了我自己的灯箱实现而这样做的。到目前为止似乎运作良好。

回答by 0b10011

This is the solution we went with. Simply save the scroll position when the overlay is opened, scroll back to the saved position any time the user attempted to scroll the page, and turn the listener off when the overlay is closed.

这是我们采用的解决方案。只需在打开覆盖层时保存滚动位置,在用户尝试滚动页面时随时滚动回保存的位置,并在覆盖层关闭时关闭侦听器。

It's a bit jumpy on IE, but works like a charm on Firefox/Chrome.

它在 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>

回答by dhc

I had a similar problem: a left-hand menu that, when it appears, prevents scrolling. As soon as height was set to 100vh, the scrollbar disappeared and the content jerked to the right.

我遇到了类似的问题:出现时会阻止滚动的左侧菜单。一旦高度设置为 100vh,滚动条就消失了,内容向右猛拉。

So if you don't mind keeping the scrollbar enabled (but setting the window to full height so it won't actually scroll anywhere) then another possibility is setting a tiny bottom margin, which will keep the scroll bars showing:

因此,如果您不介意启用滚动条(但将窗口设置为全高,因此它实际上不会滚动到任何地方),那么另一种可能性是设置一个很小的底部边距,这将使滚动条保持显示:

body {
    height: 100vh;
    overflow: hidden;
    margin: 0 0 1px;
}

回答by Marek C

<div id="lightbox">is inside the <body>element, thus when you scroll the lightbox you also scroll the body. The solution is to not extend the <body>element over 100%, to place the long content inside another divelement and to add a scrollbar if needed to this divelement with overflow: auto.

<div id="lightbox">位于<body>元素内部,因此当您滚动灯箱时,您也会滚动正文。解决方案是不要将<body>元素扩展到100% 以上,将长内容放置在另一个div元素中,并在需要时div使用overflow: auto.

html {
  height: 100%
}
body {
  margin: 0;
  height: 100%
}
#content {
  height: 100%;
  overflow: auto;
}
#lightbox {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
}
<html>
  <body>
    <div id="content">much content</div>
    <div id="lightbox">lightbox<div>
  </body>
</html>

Now, scrolling over the lightbox (and the bodyas well) has no effect, because the body is no longer than 100% of the screen height.

现在,滚动灯箱(以及灯箱body)没有任何效果,因为主体不超过屏幕高度的 100%。