Languages
[Edit]
EN

JavaScript - check for scrollTo() method got finished

10 points
Created by:
Hayley-Mooney
677

In this article, we would like to show how to detect when scrollTo() method finished execution in JavaScript.

There is not available event that signals when scrollTo() method ends execution, so there is needed to use some trick to solve the problem. In the example solution we provide reusable logic that checks state once per some time.

Example solution:

function SmoothScroller(element, interval = 100, chances = 3, tolerance = 1.0) {
    const bound = tolerance * tolerance;
    let id = null;
    this.scroll = (x, y, callback) => {
        if (id) {
            clearTimeout(id);
            id = null;
        }
        const options = {
            left: x,
            top: y,
            behavior: 'smooth'
        };
        element.scrollTo(options);
        if (callback) {
            let state = +Infinity;
            const action = () => {
                const elementX = element.scrollLeft;
                const elementY = element.scrollTop;
                const dx = x - elementX;
                const dy = y - elementY;
                const square = dx * dx + dy * dy;
                if (square < bound) {
                    callback('done');
                } else {
                    if (square === state) {
                        if (chances > 0) {
                            state = square;
                            chances -= 1;
                            id = setTimeout(action, interval);
                        } else {
                            callback('canceled');
                        }
                    } else {
                        state = square;
                        id = setTimeout(action, interval);
                    }
                }
            };
            id = setTimeout(action, interval);
        }
    };
    this.stop = () => {
        if (id) {
            clearTimeout(id);
            id = null;
        }
    };
}


// Usage example:

const element = ...  // e.g. document.querySelector('#element');
const scroller = new SmoothScroller(element);

scroller.scroll(50, 100, (status) => console.log(`status: ${status}`));  // scrolls into (x, y) = (50, 100) position

Where:

  • in SmoothScroller class constructor:
    • element represents handle to HTML element that is scrolled,
    • interval means how often state checking is done, e.g. 100 means once per 100ms,
    • chances means how many state failing checks are accepted, e.g. when something or someone tries to stop scrolling ro changes scrolling destination point,
    • tolerance was introduced to makes possible floating-point values usage by web browser when window has sets zoom,
  • in scroll() method:
    • x and y means scrolling destination point,
    • callback means function called when scrolling is done or canceled.

 

Practical example

// ONLINE-RUNNER:browser;

<style>

    div.element {
        border: 1px solid silver;
        width: 400px;
        height: 300px;
        white-space: nowrap;
        overflow: auto;
    }

</style>
<script>

    // Common reusable logic:

    function SmoothScroller(element, interval = 100, chances = 3, tolerance = 1.0) {
        const bound = tolerance * tolerance;
        let id = null;
        this.scroll = (x, y, callback) => {
            if (id) {
                clearTimeout(id);
                id = null;
            }
            const options = {
                left: x,
                top: y,
                behavior: 'smooth'
            };
            element.scrollTo(options);
            if (callback) {
                let state = +Infinity;
                const action = () => {
                    const elementX = element.scrollLeft;
                    const elementY = element.scrollTop;
                    const dx = x - elementX;
                    const dy = y - elementY;
                    const square = dx * dx + dy * dy;
                    if (square < bound) {
                        callback('done');
                    } else {
                        if (square === state) {
                            if (chances > 0) {
                                state = square;
                                chances -= 1;
                                id = setTimeout(action, interval);
                            } else {
                                callback('canceled');
                            }
                        } else {
                            state = square;
                            id = setTimeout(action, interval);
                        }
                    }
                };
                id = setTimeout(action, interval);
            }
        };
        this.stop = () => {
            if (id) {
                clearTimeout(id);
                id = null;
            }
        };
    }

</script>
<button onclick="scrollElement(0, 0)">Scroll to (0, 0)</button>
<button onclick="scrollElement(400, 500)">Scroll to (400, 500)</button>
<button onclick="scrollElement(0, 1000)">Scroll to (0, 1000)</button>
<br /><br />
<div class="element" id="element">
    <!-- Automatically generated text is placed here ... -->
</div>
<script>

    const handle = document.querySelector('#element');

    // Element content preparation:

    let text = '';
    for (let i = 0; i < 100; ++i) {
        for (let j = 0; j < 10; ++j) {
            text += 'Verry long line ...';
        }
        text += '\n';
    }
    handle.innerText = text;

    // Element scroller usage:

    const scroller = new SmoothScroller(handle);
    function scrollElement(x, y) {
        const callback = (status) => {
            console.log(`status: ${status}`);
        };
        scroller.scroll(x, y, callback);
    }

</script>

 

See also

  1. JavaScript - scroll stop event

Alternative titles

  1. JavaScript - check whether the scrollTo() method has completed
  2. JavaScript - detect when scrollTo() method finished execution
Donate to Dirask
Our content is created by volunteers - like Wikipedia. If you think, the things we do are good, donate us. Thanks!
Join to our subscribers to be up to date with content, news and offers.
Native Advertising
🚀
Get your tech brand or product in front of software developers.
For more information Contact us
Dirask - we help you to
solve coding problems.
Ask question.

❤️💻 🙂

Join