为什么scrollTop会有小数部分?

3

当我点击视频播放时,尝试滚动具有大量数据的div。

我遇到了一个奇怪的问题,我的scrollTop为211.25,但我的scrollHeight711,clientHeight为500px

我必须在scrollTop上使用Math.floor使其成为偶数。

这个.25px从哪里来?

HTML:

<video id="v0" tabindex="0" autobuffer="autobuffer" preload="preload" controls>
  <source src="http://res.cloudinary.com/david-wash-blog/video/upload/sample-video.mp4" type="video/mp4"></source>
  <p>Sorry, your browser does not support the &lt;video&gt; element.</p>
</video> 
<div id="data-scroll">
   SOME DATA
   SOME DATA
   SOME DATA
   SOME DATA
   SOME DATA
   SOME DATA

</div> 

CSS:
#v0 {
  width: 100%;
  height: 200px;
}

#data-scroll {
  width: 500px; 
  height: 500px;
  overflow-y: scroll; 
  border: solid red 10px;
}
#footer {
  height: 400px;
}

JavaScript:
(function(){
  var vid = document.getElementById('v0'); 
  var dataScroll = document.getElementById('data-scroll');
  var controls = document.getElementById('controls');


  function playScroll(){
      console.log(`clientHeight:${dataScroll.clientHeight}`);
      console.log(`scrollHeight: ${dataScroll.scrollHeight}`);
      console.log(`scrolling dataScroll @ ${dataScroll.scrollTop}`);
      script.scrollTop += 100;
      if(dataScroll.scrollHeight - Math.floor(dataScroll.scrollTop) === script.clientHeight){
        console.log(`stop scrolling dataScroll @ ${dataScroll.scrollTop}`);
        window.cancelAnimationFrame(playScroll);
      }
      window.requestAnimationFrame(playScroll);
    }

  vid.addEventListener('play', function(){
    window.requestAnimationFrame(playScroll);
  });
}());

2
嗯,我们无法确定您具体的情况,因为代码是不完整的,但是想象一下,如果您有一张宽度为400像素、高度为300像素的图像,但是以525.0像素的宽度显示,那么高度将变为393.75像素。这会影响下方的所有内容块。检查页面,您可能会发现类似这样的情况。 - KIKO Software
2
根据规格说明,"在使用显示缩放的系统上,scrollTop可能会返回一个小数值。" https://developer.mozilla.org/zh-CN/docs/Web/API/Element/scrollTop - ecg8
是的,我看到了,但是什么是显示缩放?这是响应式设计吗?这是用于较小的值吗?我不明白他们在这里所指的显示缩放是什么意思。 - Kyle Calica-St
我假设"显示缩放"意味着设置显示比例为100%以外的值,例如https://images.idgesg.net/images/article/2018/07/scalingwindows10-100764460-large.jpg - 但是为什么你要测试相等性而不是scrollTop >= scrollHeight - clientHeight呢? - Nickolay
scrollTop >= scrollHeight - clientHeight 不总是有效,因为有时候比较结果可能会像 100.75 >= 101 这样,由于 100.75 没有被进位到 101(而且在这个例子中 scrollTop 的值永远不会大于 100.75),所以检查失败。在我的测试中,Math.round(scrollTop) >= scrollHeight - clientHeight 在我遇到的情况下似乎总能奏效。我一直在想为什么人们设计 API 的方式会是这样... 哦,就让这个四舍五入吧,那个跳过吧。 - trusktr
显示剩余3条评论
1个回答

2
为什么scrollTop有小数部分?
因为网络规范作者认为这是一种奇怪的随机原因,字面上来说。
最可能你要找的是这个:
// It reached the bottom.
Math.round(scrollTop) >= scrollHeight - clientHeight

到目前为止,这对我来说一直有效。我还不知道有什么更好的方法,但如果我找到了,我会更新它。

编辑:之前的方法并不总是有效。有时在四舍五入后,scrollTop会略微多或少于scrollHeight - clientHeight,特别是在内容被缩放(例如缩放或CSS变换)的情况下。

这就是我现在正在使用的方法,使用Math.abs来处理多或少的情况:

function isScrolledToBottom(el) {
    // NOTE: scrollTop is fractional, while scrollHeight and clientHeight are
    // not, so without this Math.abs() trick then sometimes the result won't
    // work because scrollTop may not be exactly equal to el.scrollHeight -
    // el.clientHeight when scrolled to the bottom.
    return Math.abs(el.scrollHeight - el.clientHeight - el.scrollTop) < 1
}

注意,我没有使用 window API,只使用了元素 API,因为这在每种滚动情况下都可以使用,包括页面的顶级滚动。
对于顶级滚动,我们可以像这样使用:
isScrolledToBottom(document.documentElement)

但我们也可以将其用于页面中嵌套在任何元素内的滚动。


1
哈哈,我已经不在这个代码库里了,但还是很高兴看到一些答案和解决方案可以学习!谢谢! - Kyle Calica-St

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接