js / css:禁用滚动条但保持滚动位置

时间:2012-09-03 20:42:10

标签: jquery css

我正在使用Jquery对话框在页面顶部打开一个弹出框窗口。 当我打开对话框时,我希望禁用常规页面滚动。 为此,我正在做:

$('body').css({overflow:'hidden'});
对话框打开时

,并且:

$('body').css({overflow:'auto'});

对话框关闭时。

这样可行,但当删除滚动条时,后面的内容会向右移动,结果不太好。

我尝试了另一种方法,通过创建一个css类“noscroll”,如下:

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

然后,我将在对话框打开/关闭时添加并删除此类,而不是之前的js代码。

现在这适用于滚动条,后面的内容不会向右移动,但使用此方法后面的内容会回到顶部。

因此,基本上,method1使内容向右移动,而method2使内容移回到顶部。

有谁知道这方面的解决方案?对话框打开时没有滚动后面的内容,禁用滚动时没有动作......?

6 个答案:

答案 0 :(得分:11)

我已经为我的解决方案做了一个非常简单的例子。

http://jsfiddle.net/6eyJm/1/

您的弹出框应该在一个框中

<div id="shadow">
<div id="popup">
    <a id='close' href="#">Close</a>
</div>

然后将这些CSS放在de root div

#shadow{
    display: none;
    position: fixed;
    top:0;
    bottom: 0;
    width: 100%;
    height:100%;
    background-color: rgba(0,0,0,0.6);
}

固定位置非常重要,因为你不想看到白色边框,它会占据整个窗口宽度而不是正面。

然后是小JS技巧

$('#open').click(function(e){
    e.preventDefault()
    $('body').width($('body').width());
    $('body').css('overflow', 'hidden');
    $('#shadow').css('display', 'block');
})
$('#close').click(function(e){
    e.preventDefault()
    $('body, #shadow').removeAttr('style')
})

此处的目标是在移除滚动条之前获取主体宽度。您的内容不会移动。

希望有所帮助!

抱歉我的英语,而不是我的母语。

答案 1 :(得分:9)

记住偏移应该保持弹出窗口;

JSfiddle

<强> HTML

<div id="popupholder">
    <button id="close">Close me</button>
</div>


asd <br />asd <br />asd <br />asd <br />asd <br />
<button class="open">Popup</button>
<br />asd <br />asd <br />asd <br />asd <br />asd <br />asd <br />asd <br />asd <br />asd<br />
<button class="open">Popup</button>
<br />asd <br />asd <br />asd <br />asd <br />asd <br />asd <br />asd <br />asd <br />asd <br />asd <br />asd <br />asd <br />asd <br />
<button class="open">Popup</button>
<br />asd <br />asd <br />asd <br />asd <br />asd <br />asd <br />asd <br />asd <br />asd <br />asd <br />asd <br />asd <br />asd <br />asd <br />asd <br />asd <br />asd <br />asd<br />
<button class="open">Popup</button>
<br />asd <br />asd <br />asd <br />asd <br />asd <br />asd <br />asd <br />asd <br />asd <br />asd <br />asd <br />

<强> CSS

html, body {
    margin: 0px;
}

#popupholder {
    width: 100%;
    height: 100%;
    position: absolute;
    display: box;
    display: -webkit-box;
    display: -moz-box;
    background-color: rgba(0,0,0,0.75);
    display: none;
}

#close {
    display: block;
    height: 20px;
    margin: 75px auto 0px auto;
}

<强>的JavaScript

$(document).ready(function() {
    $('.open').click(function() {
        // Block scrolling
        $('body').css('overflow', 'hidden');

        // Show popup
        var offset = window.pageYOffset;
        //console.log(offset);
        $('#popupholder').css({
            'display': 'block',
            'top': offset + 'px'
        });
    });

    $('#close').click(function() {
        // Enable scrolling
        $('body').css('overflow', 'auto');

        // Hide popup
        $('#popupholder').css('display', 'none');
    });
});

出于安全原因,您可以为z-index添加一个非常高的#popupholder,但这与问题无关。

答案 2 :(得分:2)

我遇到了同样的问题,这个存储库帮助了我no-scroll

答案 3 :(得分:2)

这是我到目前为止获得的最佳解决方案。相信我,我尝试了所有其他方法,这是我想出的最好,最简单的解决方案。 在Windows设备上运行很好,它将页面向右推,以为系统滚动条和 IOS设备留出空间,这些浏览器在浏览器中不需要空格。因此,通过使用此选项,您无需在右侧添加填充,因此当您使用CSS将正文或html的隐藏隐藏时,页面不会闪烁。

考虑一下,该解决方案非常简单。这个想法是在打开弹出窗口时为 window.scrollTop()提供相同的精确位置。当窗口调整大小时,也要更改该位置(滚动位置一旦发生更改,就改变了)。

所以我们开始...

首先让我们创建一个变量,该变量将使您知道弹出窗口已打开,并将其命名为 stopWindowScroll 。如果我们不这样做,那么您会在页面上看到未定义变量的错误,并将其设置为0-未激活。

@procedure.owner
@procedure.assignee

现在,让打开的弹出窗口功能成为您代码中任何可触发您用作插件或自定义弹出窗口的函数。在这种情况下,这将是一个简单的自定义弹出窗口,并带有单击功能的简单文档。

$(document).ready(function(){
    stopWindowScroll = 0;
});

因此,我们下一步要做的是创建关闭弹出窗口功能,我再说一遍,它可以是您已经创建或正在插件中使用的任何功能。重要的是,我们需要这两个函数将 stopWindowScroll 变量设置为1或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);
});

然后让我们创建window.scroll函数,以便一旦上述 stopWindowScroll 设置为1-处于活动状态,就可以防止滚动。

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

就这样。除了您自己的页面样式外,不需要CSS即可运行。这对我来说就像是一种魅力,希望对您和其他人有帮助。

这是JSFiddle上的一个有效示例:

JS Fiddle Example

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

答案 4 :(得分:1)

你可以计算隐藏溢出之前和之后的身体宽度之间的差异,并将其作为填充权利应用于身体

var bodyStartW = $("body").width();
$("body").css("overflow-y" , "hidden");
var bodyEndW = $("body").width();
var bodyMarginL = bodyEndW - bodyStartW;
$("body").css("padding-right" , bodyMarginL);

在Safari中你对“html”标签有同样的技巧,而右边缘也没有填充右边

答案 5 :(得分:1)

我将这两个功能用于相同的目的:

function enableBodyScroll() {
  if (document.readyState === 'complete') {
    document.body.style.position = '';
    document.body.style.overflowY = '';

    if (document.body.style.marginTop) {
      const scrollTop = -parseInt(document.body.style.marginTop, 10);
      document.body.style.marginTop = '';
      window.scrollTo(window.pageXOffset, scrollTop);
    }
  } else {
    window.addEventListener('load', enableBodyScroll);
  }
}

function disableBodyScroll({ savePosition = false } = {}) {
  if (document.readyState === 'complete') {
    if (document.body.scrollHeight > window.innerHeight) {
      if (savePosition) document.body.style.marginTop = `-${window.pageYOffset}px`;
      document.body.style.position = 'fixed';
      document.body.style.overflowY = 'scroll';
    }
  } else {
    window.addEventListener('load', () => disableBodyScroll({ savePosition }));
  }
}

工作原理:

  1. 要在保存当前位置的同时禁用滚动,请运行disableBodyScroll({ savePosition: true })

  2. 该功能检查页面是否已加载(因为用户可能在加载过程中触发对话框打开)。

  3. 如果页面已加载,则通过在margin-top上设置body来保存当前滚动位置,然后在页面上设置position: fixed; overflow-y: scroll来删除滚动条。

  4. 如果未加载页面,则会在页面加载时添加事件监听器以运行(3。)。

要启用滚动,所有操作都是相同的,但是该功能会删除样式,而不是设置样式。

代码源:https://github.com/funbox/diamonds/blob/master/lib/body-scroll.ts