Reputation: 10282
Disclaimer: I am not a JavaScript developer, I'm a web designer. HTML and CSS, I handle all day, JS, not so much. That's why I'm reaching out for help.
The following script allows for a smooth scroll to the top of the page:
function scrollToTop() {
var position =
document.body.scrollTop || document.documentElement.scrollTop;
if (position) {
window.scrollBy(0, -Math.max(1, Math.floor(position / 10)));
scrollAnimation = setTimeout("scrollToTop()", 30);
} else clearTimeout(scrollAnimation);
}
Is there a way to "stop" the script from executing if the user decides to scroll back down the moment the script is running and taking the user back to the top of the page?
Here's a demo for reference: https://codepen.io/ricardozea/pen/ewBzyO
Thank you.
Upvotes: 0
Views: 109
Reputation: 10282
Thanks a lot for your answers!
After consulting with a friend of mine, he provided me with a much succinct way to accomplish the overall behavior of smooth scrolling to the top while solving the potential case of a user wanting to scroll back down during the animation.
Just add this script to a <button>
element in the onclick:
attribute:
window.scrollTo({top: 0, behavior: "smooth"});
It looks like this:
<button onclick='window.scrollTo({top: 0, behavior: "smooth"});'>Back to Top ↑</button>
Here's a new demo: https://codepen.io/ricardozea/pen/NWpgyjL
Upvotes: 0
Reputation: 120538
To specifically detect scrolling back down the page, you could check the old postion against the current position and ensure the scroll is moving in the intended direction:
function scrollToTop(prevPosition) {
// first time round, prevPosition is undefined
var position =
document.body.scrollTop || document.documentElement.scrollTop;
// did page move in non-expected direction? If so, bail-out
if (prevPosition <= position) {
return;
}
var scrollAnimation; //declare this so it doesn't leak onto global scope
if (position) {
var scrollAmt = -Math.max(1, Math.floor(position / 10));
window.scrollBy(0, scrollAmt);
// After timeout, re-call the function with current position.
// Becomes prevPosition for the next time round
scrollAnimation = setTimeout(() => scrollToTop(position), 30);
} else clearTimeout(scrollAnimation);
}
See https://codepen.io/spender/pen/eYvRyox
Why not listen to wheel events? This won't detect dragging the scrollbar with the mouse.
Upvotes: 1