21

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

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

当对话框打开时,并且:

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

当对话框关闭时。

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

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

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

然后,而不是以前的 js 代码,我在对话框打开/关闭时将此类添加和删除到正文中。

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

所以基本上method1使内容向右移动,method2使内容回到顶部。

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

4

6 回答 6

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')
})

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

希望对您有所帮助!

对不起我的英语,不是我的母语。

于 2013-04-26T14:08:30.807 回答
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,但这与问题并不真正相关。

于 2013-04-21T18:53:49.783 回答
3

我有同样的问题这个存储库帮助我无滚动

于 2018-08-17T16:53:36.910 回答
3

这是迄今为止我得到的最好的解决方案。相信我,我尝试了所有其他方法,这是我想出的最好和最简单的解决方案。它在 Windows 设备上运行良好,从右侧推动页面为系统滚动条和IOS 设备留出空间,而 IOS 设备在浏览器中不需要滚动条空间。因此,通过使用它,您不需要在右侧添加填充,这样当您使用 css 隐藏 body 或 html 的溢出时,页面不会闪烁。

如果您考虑一下,解决方案非常简单。这个想法是在打开弹出窗口的那一刻给window.scrollTop()相同的确切位置。当窗口调整大小时也更改该位置(因为一旦发生滚动位置就会更改)。

所以我们开始...

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

$(document).ready(function(){
    stopWindowScroll = 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);
});

所以接下来我们要做的是创建关闭弹出功能,我再重复一遍,它可以是您已经创建或正在插件中使用的任何功能。重要的是我们需要这 2 个函数将stopWindowScroll变量设置为 1 或 0 以了解它何时打开或关闭。

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

然后让我们创建 window.scroll 函数,这样我们就可以在上面提到的stopWindowScroll设置为 1 时阻止滚动 - 激活。

$(window).scroll(function(){
    if(stopWindowScroll == 1) {
         // Giving the window scrollTop() function the position on which
         // the popup was opened, this way it will stay in its place.
         $(window).scrollTop(stopWindowScrollPosition);
    }
});

就是这样。除了您自己的页面样式外,无需任何 CSS 即可工作。这对我来说就像一个魅力,我希望它可以帮助你和其他人。

这是一个关于 JSFiddle 的工作示例:

JS 小提琴示例

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

于 2018-09-13T13:59:59.543 回答
1

您可以计算溢出隐藏之前和之后的正文宽度之间的差异,并将其作为 padding-right 应用于正文

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

在 Safari 中,您对“html”标签有相同的技巧,并且使用 margin-right 而不是 padding-right

于 2013-09-30T13:31:11.540 回答
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-topon body,然后设置position: fixed; overflow-y: scroll它以删除滚动条。

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

为了启用滚动,一切都是一样的,但功能是删除样式而不是设置它们。

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

于 2020-08-02T21:15:20.720 回答