javascriptjquerytimersetintervalinview

Clearing an interval does not work


I'm working on a rather strange and complex function. The idea is that there is a timer that runs a slider. This timer gets cleared when the slider is hovered (i.e. the slider stopts moving). I would also like the timer to be cleared when the slider (or, rather, its parent container) is out of view. With the plugin inview I can check if an element is in the viewport or not. So when I see that the parent element is not in the viewport anymore, I clear the timer. However, this is not working and I can't figure out why. Clearing the timer on hover does work. Here is a fiddle.

The part that is not working:

$("body > .section").bind('inview', function (event, isInView) {
    var $this = $(this);

    if (isInView) {
        // Päuse Twitter slider if it's not in the viewport
        if (!$this.is(".twitter")) {
            clearInterval(timer);
            console.log("Timer cleared");
            $(".twitter .article.focus").addClass("pause");
        } else {
            $(".twitter .article").removeClass("pause");
            startTimer();
            console.log("Timer restart");
        }
    }
});

As you can see, the events are logged in console, so they are triggered, but the slider does not stop (as you can see in console: classes are still assigned and remove to the .articles inside .twitter. This means that the timer isn't cleared. But why not? I can't figure it out. The timer is set globally, so that should not be a problem.

EDIT: oh apparently the clearing of the timer on hover doesn't work either... It is strange, because all the console.logs do work. AND timer is set as a global variable.


Solution

  • The key is not to start the timer more times. The inview jQuery plugin fires the inview event anytime you reach top or bottom of the watched element and in your example you start new timer everytime this happens. And since the new timer replaces the timer you already had set up, you lose track of that old timer and cannot clear it afterwards.

    Try abstracting the start & pause code and everytime you start, check if the timer is started. For example like this:

    function startSlider() {
        if (!timer) {
            startTimer();
        }
    }
    
    function pauseSlider() {
        clearInterval(timer);
        timer = null;
    }
    

    I have updated the jsfiddle where you can see it working in action.