skip to Main Content

I have a short code that runs a setInterval only when the element is in view, but for some reason it won’t cancel when the element gets out of view. I don’t know if I misunderstood InteractionObserver or why the clearInterval doesn’t work, but if I log in else it logs to the console.

         let callback = (entries, observer) => {
            entries.forEach(entry => {
                let intval;
                if(entry.isIntersecting) {
                    const functionToRun = () => {console.log('running');}
                    intval = setInterval(functionToRun, random(500, 2000))
                } else {
                    clearInterval(intval);
                }
            })
        }
        let observer = new IntersectionObserver(callback, {
            threshold: [0.1]
        });
        observer.observe(elementToObserve);

2

Answers


  1. The observer callback is being called everytime the item enter/exit the viewport.

    Your intval is being created everytime the callback is invoked, so you lost the reference to your previous timeoutId obtained in setInterval.

    In order to solve this, a recommendation is to use WeakMap to store a reference to your timeoutId, where the key is the element, example below:

    const map = new WeakMap();
    if (entry.isIntersecting) {
        map.set(entry.target, setInterval(functionToRun, random(500, 2000)));
    } else {
        clearInterval(map.get(entry.target));
    }
    
    Login or Signup to reply.
  2. You need to keep intval variable outside of your observer callback since it will be called multiple times, causing setInterval to lose its return interval ID.

    let intval;
    let callback = (entries, observer) => {
      entries.forEach((entry) => {
        if (entry.isIntersecting) {
          const functionToRun = () => {
            console.log("running");
          };
          intval = setInterval(functionToRun, random(500, 2000));
        } else {
          clearInterval(intval);
        }
      });
    };
    let observer = new IntersectionObserver(callback, {
      threshold: [0.1],
    });
    observer.observe(elementToObserve);
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search