【问题标题】:Disable scroll on body when modal view open模态视图打开时禁用正文滚动
【发布时间】:2014-03-02 22:23:00
【问题描述】:

我找到了一个 JQuery 解决方案,可以在打开模式视图时禁用正文滚动,但我正在寻找一个 Javascript 解决方案,谁能告诉我如何转换为 JS:

$(function () {
var $body = $(window.document.body);

function bodyFreezeScroll() {
    var bodyWidth = $body.innerWidth();
    $body.css('overflow', 'hidden');
    $body.css('marginRight', ($body.css('marginRight') ? '+=' : '') + ($body.innerWidth() - bodyWidth))
}

function bodyUnfreezeScroll() {
    var bodyWidth = $body.innerWidth();
    $body.css('marginRight', '-=' + (bodyWidth - $body.innerWidth()))
    $body.css('overflow', 'auto');
}

$('.modal').hide()

$('.longcontent.main button').click(function () {
    $('.modal').show()
    bodyFreezeScroll()
})
$('.modal button').click(function () {
    $('.modal').hide()
    bodyUnfreezeScroll()
})})

http://jsfiddle.net/ngwhk/

【问题讨论】:

  • 你想把哪一部分翻译成 vanilla js?诀窍是拥有一个与当前视口一样大的“背景”容器(上:0;右:0;下:0;左:0;)此容器具有 css 属性overflow: auto(或滚动)所以视口更大的内容可以滚动。然后你可以将它应用到正文中,只要打开拨号:document.body.style.overflow = "hidden";
  • 是的,禁用滚动并重新启用它效果很好,但是有一个隐藏和显示滚动条的动画,宽度会改变我想获得这一行的等效项:` $body.css('marginRight', ($body.css('marginRight') ? '+=' : '') + ($body.innerWidth() - bodyWidth))`
  • 我在你的 jsfiddle 中没有看到动画。这只会为正文添加一个边距。
  • 这里是我想要实施解决方案的地方:jsfiddle.net/3xv6A/424
  • 问题是,当模态视图打开时,由于滚动条将被隐藏,身体向右移动,当滚动条再次返回时,它向左移动,所以我不想有这个问题

标签: javascript jquery html css


【解决方案1】:

我能想到的最好的 vanilla js 是这样的:

http://jsfiddle.net/ngwhk/23/

var $body = window.document.body;
var $modal = document.getElementsByClassName("modal")[0];
var aOpenButtons = document.getElementsByClassName("open-modal");
var aCloseButtons = document.getElementsByClassName("close-modal");


function bodyFreezeScroll($obj) {
    $body.style.overflow = "hidden";
    $body.style.marginRight = getScrollBarWidth()+"px";
}

function bodyUnfreezeScroll() {
    $body.style.overflow = "auto";
    $body.style.marginRight = "auto";
}


function showModal(){
    $modal.classList.add("visible");
    $modal.classList.remove("hide");
}

function hideModal(){
    $modal.classList.add("hide");
    $modal.classList.remove("visible");
}


for(var i = 0, a=aOpenButtons.length; i<a; i++){
   aOpenButtons[i].addEventListener("click", function(){
    showModal();
    bodyFreezeScroll();
    }, false); 
}

for(var i = 0, a=aCloseButtons.length; i<a; i++){
   aCloseButtons[i].addEventListener("click", function(){
    hideModal();
    bodyUnfreezeScroll();
    }, false);
}

function getScrollBarWidth() {
    /* found here: https://stackoverflow.com/questions/986937/how-can-i-get-the-browsers-scrollbar-sizes */
  var inner = document.createElement('p');
  inner.style.width = "100%";
  inner.style.height = "200px";

  var outer = document.createElement('div');
  outer.style.position = "absolute";
  outer.style.top = "0px";
  outer.style.left = "0px";
  outer.style.visibility = "hidden";
  outer.style.width = "200px";
  outer.style.height = "150px";
  outer.style.overflow = "hidden";
  outer.appendChild (inner);

  document.body.appendChild (outer);
  var w1 = inner.offsetWidth;
  outer.style.overflow = 'scroll';
  var w2 = inner.offsetWidth;
  if (w1 == w2) w2 = outer.clientWidth;

  document.body.removeChild (outer);

  return (w1 - w2);
};

更新
我从这里的答案中找到了一种测量滚动条宽度的方法:How can I get the browser's scrollbar sizes?

由于似乎没有触发过渡,所以当我更改样式或添加类时(如果您知道方法,请更正此问题)我为此添加了关键帧动画。

@keyframes show {
  0%   { top: -100%; }
  100% { top: 0; }
}

@keyframes hide {
  0%   { top: 0%; }
  100% { top: -100%; }
}

【讨论】:

  • 感谢您的努力,但是我们可以防止两个滚动条在过渡动画中一起显示
  • 找到了一种方法来获取当前滚动条的正确大小,并更新了小提琴+答案。请参阅参考资料。
猜你喜欢
  • 2015-07-05
  • 2019-07-14
  • 1970-01-01
  • 1970-01-01
  • 2014-03-31
  • 2019-10-14
  • 2017-02-10
  • 2016-11-10
  • 2012-03-07
相关资源
最近更新 更多