Search code examples
javascriptcountdownclearintervalswiper.js

Javascript clearInterval not reseting countdown value


I'm making a swiper slider. My goal is to have a countdown that reset's its value every slide change. If slides changes automatically the countdown reset's well and starts counting down again on next slide. The problem is that if i click on the navigation dots then i have some sort of double countdown. I think clearInterval starts another countdown but the previous countdowns are not removed from the thread execution.

var autoplay = 20000;
var swiper = new Swiper('.swiper-container', {
    pagination: '.swiper-pagination',
    paginationClickable: true,
    watchSlidesProgress: true,
    autoplay: 20000,
    onProgress: elipse
});

function elipse() {
    clearInterval(timer);
    var countdownNumberEl = document.getElementById('countdown-number');
    var countdown = 20;
    countdownNumberEl.textContent = countdown;
    var timer = setInterval(frame, 1000);
    function frame(){
        countdown = --countdown <= 0 ? 20 : countdown;
        countdownNumberEl.textContent = countdown;
    }
}

var swiperBullet = document.getElementsByClassName("swiper-pagination-bullet");
for (var i = 0; i < swiperBullet.length; i++) {
    swiperBullet[i].addEventListener('click', function () {
        elipse();
    });
}

Can somebody help me resolve what is going on?


Solution

  • In your case timer is still not declared and it's undefined

    function elipse() {
        //timer will be undefined or throw error that is not declared
        //so you are not clearing anything
        console.log(timer);
        clearInterval(timer);
        //stuff
    
        //this wil redaclare timer every time you enter the function and it will return different intervalID
        //so this will grow exponentially
        var timer = setInterval(function () {
            elipse()
        }, 1000);
    }
    elipse()

    So you must declare timer out of the scope for function elipse it's not necessary to be a global variable just out of the scope for example:

    (function () {
      var timer;
      function elipse() {
          //only the first time will be undefined
          console.log(timer);
          clearInterval(timer);
          //just don't redeclared timer becouse it will be for this scope and it will create a new intervalID that you can't access
          timer = setInterval(function () {
              elipse()
          }, 1000);
      }
      elipse()
    })();

    P.S. clearInterval expects intervalID

    The identifier of the repeated action you want to cancel. This ID was returned by the corresponding call to setInterval().

    And setInterval Return value is a numeric, non-zero value

    So in my opinion undefined won't cause troubles