【问题标题】:How to prevent scrolling? (cross-browser workaround)如何防止滚动? (跨浏览器解决方法)
【发布时间】:2017-03-14 00:23:24
【问题描述】:

问题或疑问

我想防止元素的实际滚动,但我确实想要滚动条的好处(所以有些事情不必用一些 JavaScript 以编程方式完成,而不是浏览器为我们处理事情) .

有没有人对此有更好或改进的解决方案?非常感谢任何帮助。

2017 年 13 月 3 日更新

我终于想出了一个似乎可行的答案(使用测试)IE11、Edge、Chrome、Firefox、Chrome for Android 和 Firefox for Android。

因此人们可以忽略此问题或问题描述的其余部分

2017 年 12 月 3 日更新

找到了一种在 IE 11、Edge、Firefox、Chrome 和 Firefox for Android 之间切换(防止)滚动的方法。虽然它在 Android 版 Chrome 中并不能很好地工作(真的很滞后)。有人知道为什么吗?

这是我的解决方案的摘要(2017 年 3 月 12 日),但 Android 版 Chrome 似乎不喜欢它(!)。请帮助改进此解决方案(或者也许有与此特定解决方案不同的更好方法?)。

  • 一个带有滚动内容的divposition: fixed(我的代码中为#scrollsviascrolldistract)。
  • 一个div 与滚动内容div 具有相同的高度,该滚动内容具有position: absolute(或者最好是position: relative)。这是嵌入式代码示例中的#scrolldistract
  • 使用回调函数调用window.requestAnimationFrame,该函数根据窗口的当前scrollTop 值调整滚动内容div (#scrollsviascrolldistract) 的marginTop 值(为此使用负边距)。
  • 那么为了控制和防止滚动,可以不更新这个marginTop值,使滚动内容div不受当前滚动条位置的影响。

在 IE 11、Edge、Firefox 和 Chrome(工作正常)和 Chrome for Android(不喜欢它)中测试了下面的代码 sn-p,还测试了 Firefox for Android(喜欢它)。似乎比将两个 div 元素与 position: fixed 一起使用要好得多。

var scrollDisabled = false;

function toggleScroll() {
  scrollDisabled = !scrollDisabled;
}

function doScroll() {
  var st;
  if (!scrollDisabled) {
    $("#scrollsviascrolldistract").css("marginTop", -$(window).scrollTop());
  }
  window.requestAnimationFrame(doScroll);
}

window.requestAnimationFrame(doScroll);

$("#scrolltoggler").on('click', toggleScroll);
body {
  background-color: whitesmoke;
}

#scrollsviascrolldistract {
  position: fixed;
  left: 0px;
  top: 0px;
  width: 100%;
}

#scrolldistract {
  position: absolute;
  left: 0;
  top: 0;
  height: 6000px;
}

.red,
.blue {
  position: relative;
  width: 100%;
  height: 300px;
}

.red {
  background-color: red;
}

.blue {
  background-color: blue;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="scrolldistract">
  <img src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7" height="6000">
</div>

<div id="scrollsviascrolldistract">
  <div class="red">BEGIN</div>
  <div class="blue"><button id="scrolltoggler">Toggle Scroll On/Off</button></div>
  <div class="red">&nbsp;</div>
  <div class="blue">&nbsp;</div>
  <div class="red">&nbsp;</div>
  <div class="blue">&nbsp;</div>
  <div class="red">&nbsp;</div>
  <div class="blue">&nbsp;</div>
  <div class="red">&nbsp;</div>
  <div class="blue">&nbsp;</div>

  <div class="red">&nbsp;</div>
  <div class="blue">&nbsp;</div>
  <div class="red">&nbsp;</div>
  <div class="blue">&nbsp;</div>
  <div class="red">&nbsp;</div>
  <div class="blue">&nbsp;</div>
  <div class="red">&nbsp;</div>
  <div class="blue">&nbsp;</div>
  <div class="red">&nbsp;</div>
  <div class="blue">END</div>
</div>

早期的解决方案(请忽略 12-03-2017;查看更新的解决方案)

所以我让一个元素滚动但不让它可见。我在其中放置了一个间隔图像以将其填充到适当的高度。

然后出现跨浏览器问题。

早期的解决方案 - 哪些有效,哪些无效?

  • 可以通过鼠标或滚动条滚动。
  • 即使 focus() 也可以使用,因此可以立即使用按键进行滚动。

Android 版 Chrome

  • 通过触摸进行滚动(应该如此)。

火狐

  • Ctrl+PageUp/Ctrl+PageDown 切换选项卡并禁用滚动,直到您抓住滚动条。
  • 可以通过按键滚动,但必须单击背景区域才能获得焦点。

安卓版火狐

  • 彻底的灾难:滚动一点后停止滚动。不知道为什么。

边缘

  • 除了focus() 之外似乎工作。需要点击文档中的某处(红/蓝块或背景)。

Internet Explorer 11

  • 只能通过鼠标工作。无法抓住焦点,甚至无法手动使用按键滚动。

代码等

Demo 在这里: https://jsfiddle.net/hn63z0jt/

一些 HTML5(带有正确的 DOCTYPE):

<div id="scrollsviascrolldistract">
  <div class="red">BEGIN</div>
  <div class="blue">&nbsp;</div>
  <div class="red">&nbsp;</div>
  <div class="blue">&nbsp;</div>
  <div class="red">&nbsp;</div>
  <div class="blue">&nbsp;</div>
  <div class="red">&nbsp;</div>
  <div class="blue">&nbsp;</div>
  <div class="red">&nbsp;</div>
  <div class="blue">&nbsp;</div>

  <div class="red">&nbsp;</div>
  <div class="blue">&nbsp;</div>
  <div class="red">&nbsp;</div>
  <div class="blue">&nbsp;</div>
  <div class="red">&nbsp;</div>
  <div class="blue">&nbsp;</div>
  <div class="red">&nbsp;</div>
  <div class="blue">&nbsp;</div>
  <div class="red">&nbsp;</div>
  <div class="blue">END</div>
</div>

一些 CSS:

body {
  background-color: whitesmoke;
}

#scrollsviascrolldistract {
  position: fixed;
  left: 0px;
  top: 0px;
}

#scrolldistract {
    position: fixed;
    left: 0;
    top: 0;
    bottom: 0;
    right: 0;
    overflow-y: scroll;
    background: rgba(0,0,0,0);
  z-index: 999;
}

.red, .blue {
  position: relative;
  width: 900px;
  height: 300px;
}

.red {
  background-color: red;
}

.blue {
  background-color: blue;
}

一些JavaScript(使用jQuery):

$(function() {
    var $window = $(window);
    var $scrollsviascrolldistract = $('#scrollsviascrolldistract');
    var $scrolldistract = $('#scrolldistract');

    $scrolldistract.focus();

    $scrolldistract.on('scroll', function() {
      var scrollTop = $scrolldistract.scrollTop();
      $scrollsviascrolldistract.css('marginTop', -scrollTop);
    });
});

【问题讨论】:

  • 请问究竟是什么驱使您如此费劲地劫持默认滚动行为?
  • 更改为position: absolute,删除脚本,它将在任何地方完美运行
  • @gyre:我想使用滚动链接效果。除其他外,我尝试了 ScrollMagic 并且某些部分有效,但我还想将滚动距离用于其他效果(改变一个元素的不透明度)而该元素与父容器保持可见,因此滚动该元素和父容器必须停止(换句话说,是粘性的)。我也尝试过诸如stickyJS之类的东西,它不适用于高度超过浏览器视口高度的元素(因为'位置:固定'的限制)。
  • @LGSon:这取决于您评论中的“它”指的是什么。我需要使用滚动距离来添加或减少元素的不透明度,而不是滚动该元素(及其父容器)的距离。另请参阅我针对 gyre 的评论。

标签: javascript jquery css html cross-browser


【解决方案1】:

我现在准备回答我自己的问题。

所以这里有一种切换(防止)滚动的方法:

  • 一个带有滚动内容的divposition: fixed(在我的代码中为#scrollsviascrolldistract)。
  • 一个div,其高度与滚动内容div 的高度相同,后者具有position: absolute(或者最好是position: relative)。这是嵌入式代码示例中的#scrolldistract
  • 使用回调函数调用window.requestAnimationFrame,该函数调整拉取器div(此处称为#puller)的marginTop值,该值应该是滚动内容div#scrollsviascrolldistract)的第一个子项到窗口的当前scrollTop 值(为此使用负边距)。起初我以为我可以拉起滚动内容本身(更改 marginTop#scrollsviascrolldistract),但这在某些浏览器中不起作用。
  • 那么为了控制和防止滚动,可以不更新这个marginTop值,使滚动内容div不受当前滚动条位置的影响。

在 IE 11、Edge、Firefox 和 Chrome 以及 Chrome for Android 和 Firefox for Android 中测试以下代码 sn-p。似乎比将两个 div 元素与 position: fixed 一起使用要好得多。

$(function() {
  var scrollDisabled = false;
  var $window = $(window);

  function doScroll() {
    var st = $window.scrollTop();
    if (!scrollDisabled) {
      console.log(st);
      if (st > 6000 - $window.innerHeight()) {
        $("#puller").css("marginTop", -(6000 - $window.innerHeight()));
      } else {
        $("#puller").css("marginTop", -st);
      }
    }
    window.requestAnimationFrame(doScroll);
  }

  window.requestAnimationFrame(doScroll);

  $("#scrolltoggler").on('click', function(e) {
    scrollDisabled = !scrollDisabled;
  });
});
#scrollsviascrolldistract {
  position: fixed;
  left: 0px;
  top: 0px;
  width: 100%;
}

#scrolldistract {
  position: absolute;
  left: 0;
  top: 0;
  width: 100%;
  height: 6000px;
}

#puller {
  position: relative;
  margin-top: 0px;
  left: 0px;
  top: 0px;
}

.red,
.blue {
  position: relative;
  margin-top: auto !important;
  width: 100%;
  height: 300px;
}

.red {
  background-color: red;
}

.blue {
  background-color: blue;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="scrolldistract">
  <img src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7" width="1" height="6000">
</div>


<div id="scrollsviascrolldistract">
  <div id="puller"></div>
  <div class="red">BEGIN</div>
  <div class="blue"><button id="scrolltoggler">Toggle Scroll On/Off</button></div>
  <div class="red">&nbsp;</div>
  <div class="blue">&nbsp;</div>
  <div class="red">&nbsp;</div>
  <div class="blue">&nbsp;</div>
  <div class="red">&nbsp;</div>
  <div class="blue">&nbsp;</div>
  <div class="red">&nbsp;</div>
  <div class="blue">&nbsp;</div>

  <div class="red">&nbsp;</div>
  <div class="blue">&nbsp;</div>
  <div class="red">&nbsp;</div>
  <div class="blue">&nbsp;</div>
  <div class="red">&nbsp;</div>
  <div class="blue">&nbsp;</div>
  <div class="red">&nbsp;</div>
  <div class="blue">&nbsp;</div>
  <div class="red">&nbsp;</div>
  <div class="blue">END</div>
</div>

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-01-22
    • 1970-01-01
    • 1970-01-01
    • 2011-10-25
    • 2019-09-03
    • 2016-03-31
    • 2014-05-03
    • 2023-02-04
    相关资源
    最近更新 更多