0

There are some components stacked on top of each other and the last component has a timer. I want the timer to start only when that component is visible on screen or when scroll is reached to that component. [REPL]

let count_val = 80;
    
let count = 0;
function startTimer() {
    let count_interval = setInterval(() => {
        count += 1;

        if(count >= count_val) {
            clearInterval(count_interval);
        }
    }, 100);
}

// check if scroll reached to component and run below function.
startTimer();

How do I achieve this?

Paolo
  • 20,112
  • 21
  • 72
  • 113
Mir Stephen
  • 1,758
  • 4
  • 23
  • 54
  • You can use https://developer.mozilla.org/en-US/docs/Web/API/Intersection_Observer_API You can use it to identify if the component is in the viewport – moshfiqrony Aug 03 '22 at 12:53
  • 1
    Does this answer your question? [Check if a user has scrolled to the bottom (not just the window, but any element)](https://stackoverflow.com/questions/3898130/check-if-a-user-has-scrolled-to-the-bottom-not-just-the-window-but-any-element) – Tom Aug 03 '22 at 12:55

1 Answers1

3

Like commented this can be achieved using Intersection Observer and an action

REPL

<script>
    let count_val = 80;
    let count = 0;

    function timer(node) {
        let interval
        const observer = new IntersectionObserver((entries) => {
            entries.forEach(entry => {
                if(entry.isIntersecting) {                  
                    interval = setInterval(() => {
                        count += 1;
                        if(count === count_val) {
                            clearInterval(interval);
                        }
                    }, 100);
                } else {
                    clearInterval(interval)
                    count = 0 
                }
            })
        })
        observer.observe(node)

        return {
            destroy: () => observer.disconnect()
        }
    }
</script>

<div use:timer>
    <p>
        Counter - {count}
    </p>
</div>

<style>
    div {
        height: 100vh;
        display: grid;
        place-items: center;
        background-color: teal;
        color: #0a0a0a;
        font-size: 4rem;
    }
</style>
Corrl
  • 6,206
  • 1
  • 10
  • 36