Ricardo Zea
Ricardo Zea

Reputation: 10282

Stop script if users scrolls

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

Answers (2)

Ricardo Zea
Ricardo Zea

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

spender
spender

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

Related Questions