I have an element that has a complex position on a page, meaning that it could have been transformed with css, it could be in a parent that has a sticky position etc…
Now, how can I compute at what value of document.scrollingElement.scrollTop
my element will first appear, and at what value it will disappear ?
If you run this code, when the element first enters the screen you will see in the console at which scroll position it did so, and then when it exited. I need to know those two values at any point in time, no matter how much scroll has already been applied, if the window has been resized etc…
let entry = false;
let exit = false;
window.addEventListener("scroll", () => {
let y = element.getBoundingClientRect().y
if (!entry && y < window.innerHeight && y + element.clientHeight >= 0) {
entry = true
console.log("element enters the screen at", window.scrollY);
}
if (entry && !exit && y + element.clientHeight < 0) {
exit = true;
console.log("element exits the screen at", window.scrollY);
}
})
setInterval(()=>{
document.scrollingElement.scrollTop++
},5)
html,
body {
margin: 0px;
}
#parent {
height: 500vh;
}
#space {
height: calc(100vh + 19px);
}
#sticky {
height: 275vh;
top: 0px;
position: sticky;
}
#element {
width: 100px;
height: 200px;
background-color: blue;
position: absolute;
top: 100px;
left: 40px;
transform: translate(100px, -30px)
}
<div id="parent">
<div id="space"></div>
<div id="sticky">
<div id="element"></div>
</div>
</div>
I have tried using element.getBoundingClientRect().y
, I have computed the initial distance from the top of the document to the top of the element by summing all of its parents’ "offsetTop" values . But for example when the element is contained in a parent that has a sticky position, and this parent is in the "fixed" state, scrolling will totally change this total offset value and mess everything up.
2
Answers
I would recommend you to get the scroll Y property from the window, instead of the element. Also, to detect if the user has scrolled I would implement a
onscroll
event listener.Check the code below:
If you want to know more about the onscroll event you can go to the documentation.
If you want to know more about the scrollY property you can go to the documentation.
Also, if you don´t want to hide the element by using
display:none;
you can useopacity:0;
orvisibility:hidden;
. Check the differences here.What do you want to do with the scrollTop value?
1. If you want to do something to the element when it has been scrolled off-screen or appears in-screen
Then you don’t have to calculate this value yourself. You can use the IntersectionObserver API: https://developer.mozilla.org/en-US/docs/Web/API/Intersection_Observer_API
2. Or if you want to do something to the element when it is a certain amount of pixels away from the screen boundaries
You might want to use the optional rootMargin option of the IntersectionObserver:
https://developer.mozilla.org/en-US/docs/Web/API/IntersectionObserver/rootMargin
3. Or if you want to do something to the element when it is fully visible in-screen
You can increase the optional threshold option of the IntersectionObserver to 1:
https://developer.mozilla.org/en-US/docs/Web/API/IntersectionObserver/thresholds
4. But if you still want to calculate the scrollTop yourself
You must add the current scrollTop value of the scrolling element to the element.getBoundingClientRect().y value.