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

Javascript 只是禁用滚动而不是隐藏它?,javascript,jquery,html,css,Javascript,Jquery,Html,Css,我试图在使用lightbox时禁用父级的html/body滚动条。这里的主要单词是disable。我不想用overflow:hidden隐藏它 原因是overflow:hidden使站点跳转并占据滚动的区域 我想知道是否可以在仍然显示滚动条的情况下禁用滚动条。您可以使用Javascript: // Classic JS window.onscroll = function(ev) { ev.preventDefault(); } // jQuery $(window).scroll(fun

我试图在使用lightbox时禁用父级的html/body滚动条。这里的主要单词是disable。我不想用
overflow:hidden隐藏它

原因是
overflow:hidden
使站点跳转并占据滚动的区域


我想知道是否可以在仍然显示滚动条的情况下禁用滚动条。

您可以使用Javascript:

// Classic JS
window.onscroll = function(ev) {
  ev.preventDefault();
}

// jQuery
$(window).scroll(function(ev) {
  ev.preventDefault();
}
然后在灯箱关闭时禁用它

但是如果你的lightbox包含一个滚动条,你将无法在它打开时滚动。这是因为
窗口
同时包含
主体
灯箱
。 因此,您必须使用如下体系结构:

<body>
  <div id="global"></div>
  <div id="lightbox"></div>
</body>


然后仅在
#global
上应用
onscroll
事件。您可以保持溢出:隐藏,但手动管理滚动位置:

在显示“保留实际滚动位置的轨迹”之前:

var scroll = [$(document).scrollTop(),$(document).scrollLeft()];
//show your lightbox and then reapply scroll position
$(document).scrollTop(scroll[0]).scrollLeft(scroll[1]);

它应该可以正常工作,但工作方式是强制滚动回到顶部,从而有效地禁用滚动:

var _stopScroll = false;
window.onload = function(event) {
    document.onscroll = function(ev) {
        if (_stopScroll) {
            document.body.scrollTop = "0px";
        }
    }
};
打开灯箱时,升起旗帜;关闭灯箱时,降下旗帜


.

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

body { position: fixed; overflow-y:scroll }
.disableScroll { position: fixed; overflow-y:scroll }
您仍然可以看到右侧的滚动条,但内容不可滚动。关闭覆盖时,只需使用恢复这些属性即可

body { position: static; overflow-y:auto }
var top = $('body').position().top;
$('body').removeClass('disableScroll').css('top', 0).scrollTop(Math.abs(top));
我提出这种方式只是因为您不需要更改任何滚动事件

更新

您还可以做一点小小的改进:如果在层打开之前通过javascript获得
document.documentElement.scrollTop
属性,您可以动态地将该值指定为body元素的
top
属性:通过这种方法,页面将保持原样,不管你是在上面还是已经滚动过

Css

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

$('body').css('top', -(document.documentElement.scrollTop) + 'px')
         .addClass('noscroll');
html.noscroll {
    position: fixed; 
    overflow-y: scroll;
    width: 100%;
}

该系统的四个小补充:

  • 将“noscroll”应用于html而不是body以防止IE中出现双滚动条
  • 在添加“noscroll”类之前,检查是否有滚动条。否则,该站点也会被新的非滚动滚动条跳转推送
  • 保留任何可能的滚动条,使整个页面不会返回顶部(如Fabrizio的更新,但您需要在添加'noscroll'类之前获取值)
  • 并非所有浏览器处理scrollTop的方式都与
  • 适用于大多数浏览器的完整解决方案:

    CSS

    $('body').css('top', -(document.documentElement.scrollTop) + 'px')
             .addClass('noscroll');
    
    html.noscroll {
        position: fixed; 
        overflow-y: scroll;
        width: 100%;
    }
    
    禁用滚动

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

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

    感谢法布里齐奥和德扬让我走上了正确的道路,感谢布罗丁戈,这就是我们所采用的解决方案。只需在覆盖打开时保存滚动位置,在用户尝试滚动页面时滚动回保存的位置,并在覆盖关闭时关闭侦听器

    它在IE上有点神经质,但在Firefox/Chrome上却很有魅力

    var body=$(“body”),
    叠加=$(“#叠加”),
    叠加显示=假,
    OverlyScrollListener=null,
    overlaySavedScrollTop=0,
    左上角=0;
    函数showOverlay(){
    重叠显示=真;
    //显示覆盖图
    叠加。添加类(“显示叠加”);
    //保存滚动位置
    OverlySavedScrollTop=body.scrollTop();
    OverlySavedScrollLeft=body.scrollLeft();
    //侦听滚动事件
    OverlyScrollListener=body.scroll(函数(){
    //滚动回保存的位置
    主体。滚动顶部(覆盖滚动顶部);
    body.scrollLeft(overlySavedScrollLeft);
    });
    }
    函数hideOverlay(){
    重叠显示=假;
    //隐藏覆盖
    覆盖。removeClass(“显示覆盖”);
    //关闭滚动侦听器
    if(overlyScrollListener){
    OverlyScrollListener.off();
    OverlyScrollListener=null;
    }
    }
    //单击切换覆盖
    $(窗口)。单击(函数(){
    如果(!overlyshown){
    showOverlay();
    }否则{
    hideOverlay();
    }
    });
    
    /*必需*/
    html,正文{边距:0;填充:0;高度:100%;背景:#fff;}
    html{溢出:隐藏;}
    正文{overflow-y:scroll;}
    /*只是为了好看*/
    .spacer{高度:300%;背景:橙色;背景:线性渐变(#ff0,#f0f)}
    .overlay{位置:固定;顶部:20px;底部:20px;左侧:20px;右侧:20px;z索引:-1;背景:#fff;框阴影:0 0 5px rgba(0,0,0,3);溢出:自动;}
    .overlay.spacer{背景:线性梯度(#88f,#0ff)}
    .overlay显示{z-index:1;}
    
    页首
    单击以切换覆盖。(仅当覆盖未打开时才可滚动。)

    页底 覆盖层顶部 单击以切换覆盖。(包含页面不再可滚动,但这是。)

    覆盖层底部
    我喜欢坚持使用“溢出:隐藏”方法,只需添加与滚动条宽度相等的填充

    获取滚动条宽度函数,按

    显示覆盖时,将“noscroll”类添加到html中,并将填充添加到正文中:

    $(html).addClass("noscroll");
    $(body).css("paddingRight", getScrollbarWidth() + "px");
    
    隐藏时,请删除类和填充:

    $(html).removeClass("noscroll");
    $(body).css("paddingRight", 0);
    
    noscroll风格就是这样:

    .noscroll { overflow: hidden; }
    
    请注意,如果有任何带有position:fixed的元素,您也需要向这些元素添加填充。

    如果包含jQuery:
    使残废 使可能 使用
    位于
    元素内,因此当您滚动灯箱时,也会滚动主体。解决方案是不将
    元素扩展到100%以上,将长内容放在另一个
    div
    元素中,并在需要时使用
    溢出:auto
    向该
    div
    元素添加滚动条

    html{
    身高:100%
    }
    身体{
    保证金:0;
    身高:100%
    }
    #内容{
    身高:100%;
    溢出:自动;
    }
    #灯箱{
    位置:固定;
    排名:0;
    左:0;
    右:0;
    B
    
    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`
    });
    
    body {
        height: 100vh;
        overflow: hidden;
        margin: 0 0 1px;
    }
    
    // disable scrolling
    $('body').bind('mousewheel touchmove', lockScroll);
    
    // enable scrolling
    $('body').unbind('mousewheel touchmove', lockScroll);
    
    
    // lock window scrolling
    function lockScroll(e) {
        e.preventDefault();
    }
    
    $('button').on('click', function() {
         $('body').bind('mousewheel touchmove', lockScroll);
    });
    
    <html style="overflow: unset;"></html>
    
    <html style="overflow: auto;"></html>
    
    .disableScroll { position: fixed; overflow-y:scroll }
    
    $('body').css('top', - ($(window).scrollTop()) + 'px').addClass('disableScroll');
    
    var top = $('body').position().top;
    $('body').removeClass('disableScroll').css('top', 0).scrollTop(Math.abs(top));
    
    .no-scroll{
      position: fixed; 
      width:100%;
      min-height:100vh;
      top:0;
      left:0;
      overflow-y:scroll!important;
    }
    
    var scrollTopPostion = 0;
    
    function scroll_pause(){
      scrollTopPostion = $(window).scrollTop();
      $("body").addClass("no-scroll").css({"top":-1*scrollTopPostion+"px"});
    }
    
    function scroll_resume(){
      $("body").removeClass("no-scroll").removeAttr("style");
      $(window).scrollTop(scrollTopPostion);
    }
    
    $(document).on("click","#DISABLEelementID",function(){
       scroll_pause();
    });
    
    $(document).on("click","#ENABLEelementID",function(){
       scroll_resume();
    });
    
    body {width: 100vw; overflow-x: hidden;}
    
    // This class applies the following styles:
    // position: fixed;
    // overflow-y: scroll;
    // width: 100%;
    const NO_SCROLL_CLASS = "bp-no-scroll";
    
    const coerceCssPixelValue = value => {
      if (value == null) {
        return "";
      }
    
      return typeof value === "string" ? value : `${value}px`;
    };
    
    export const blockScroll = () => {
      const html = document.documentElement;
      const documentRect = html.getBoundingClientRect();
      const { body } = document;
    
      // Cache the current scroll position to be restored later.
      const cachedScrollPosition =
        -documentRect.top || body.scrollTop || window.scrollY || document.scrollTop || 0;
    
      // Cache the current inline `top` value in case the user has set it.
      const cachedHTMLTop = html.style.top || "";
    
      // Using `html` instead of `body`, because `body` may have a user agent margin,
      // whereas `html` is guaranteed not to have one.
      html.style.top = coerceCssPixelValue(-cachedScrollPosition);
    
      // Set the magic class.
      html.classList.add(NO_SCROLL_CLASS);
    
      // Return a function to remove the scroll block.
      return () => {
        const htmlStyle = html.style;
        const bodyStyle = body.style;
    
        // We will need to seamlessly restore the original scroll position using
        // `window.scroll`. To do that we will change the scroll behavior to `auto`.
        // Here we cache the current scroll behavior to restore it later.
        const previousHtmlScrollBehavior = htmlStyle.scrollBehavior || "";
        const previousBodyScrollBehavior = bodyStyle.scrollBehavior || "";
    
        // Restore the original inline `top` value.
        htmlStyle.top = cachedHTMLTop;
    
        // Remove the magic class.
        html.classList.remove(NO_SCROLL_CLASS);
    
        // Disable user-defined smooth scrolling temporarily while we restore the scroll position.
        htmlStyle.scrollBehavior = bodyStyle.scrollBehavior = "auto";
    
        // Restore the original scroll position.
        window.scroll({
          top: cachedScrollPosition.top
        });
    
        // Restore the original scroll behavior.
        htmlStyle.scrollBehavior = previousHtmlScrollBehavior;
        bodyStyle.scrollBehavior = previousBodyScrollBehavior;
      };
    };
    
    export const blockScroll = () => {
      const html = document.documentElement;
      const documentRect = html.getBoundingClientRect();
      const { body } = document;
      const screenHeight = window.innerHeight;
    
      // Only do the magic if document is scrollable
      if (documentRect.height > screenHeight) {
        const cachedScrollPosition =
          -documentRect.top || body.scrollTop || window.scrollY || document.scrollTop || 0;
    
        html.style.top = coerceCssPixelValue(-cachedScrollPosition);
    
        html.classList.add(NO_SCROLL_CLASS);
    
        return () => {
          html.classList.remove(NO_SCROLL_CLASS);
    
          window.scroll({
            top: cachedScrollPosition,
            behavior: "auto"
          });
        };
      }
    };
    
    const handleWheelScroll = (element) => (event) => {
      if (!element) {
        throw Error("Element for scroll was not found");
      }
      const { deltaY } = event;
      const { clientHeight, scrollTop, scrollHeight } = element;
      if (deltaY < 0) {
        if (-deltaY > scrollTop) {
          element.scrollBy({
            top: -scrollTop,
            behavior: "smooth",
          });
          event.stopPropagation();
          event.preventDefault();
        }
        return;
      }
    
      if (deltaY > scrollHeight - clientHeight - scrollTop) {
        element.scrollBy({
          top: scrollHeight - clientHeight - scrollTop,
          behavior: "smooth",
        });
        event.stopPropagation();
        event.preventDefault();
        return;
      }
    };
    
    const wheelEventHandler = handleWheelScroll(elementToScrollIn);
    
    window.addEventListener("wheel", wheelEventHandler, {
        passive: false,
    });
    
    window.removeEventListener("wheel", wheelEventHandler);
    
    import {
        pushScrollLock,
        removeScrollLock,
    } from '@polymer/iron-overlay-behavior/iron-scroll-manager';
    
    // lock scroll everywhere except scrollElement
    pushScrollLock(scrollElement);
    
    // restore scrolling
    removeScrollLock(scrollElement);