'Why does scrollTop has a fractional part?
Trying to scroll down a div with a lot of data when I press play on a video.
I get this weird issue where my scrollTop is 211.25 but my scrollHeight is 711 and clientHeight is 500px
I had to put a Math.floor on scrollTop to get it to an even number.
Where is this .25px coming from?
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 <video> 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);
});
}());
Solution 1:[1]
Why does scrollTop has a fractional part?
Because web spec authors felt like it for some odd random reason, literally.
Most likely what you're looking for is this:
// It reached the bottom.
Math.round(scrollTop) >= scrollHeight - clientHeight
So far that has been working for me. I don't know of anything better yet, but if I find out, I'll update it.
EDIT: The previous one doesn't always work. Sometimes scrollTop will be slightly more or less than scrollHeight - clientHeight after rounding, especially in cases when content is scaled (f.e. zoom or CSS transforms).
This is what I'm using now, working well, with Math.abs to handle the more-or-less case:
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
}
Note, I'm not using window APIs, only element APIs because this works in every scroll case, including for the top level scroll of the page.
For top level scroll, we can use it like this:
isScrolledToBottom(document.documentElement)
but we can also use it for scroll within any element nested anywhere in the page.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 |
