Search code examples
jquerytimersettimeoutsetinterval

jQuery: Issue with window.timer using setTimeout and setInterval for multiple elements


I'm having multiple functions using window timer to create animation and events but once I add more than one function the actions don't behave as they should I guess because the window.timer overlapping

<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1"
      viewBox="0 0 200 200" preserveAspectRatio="none" class="circle_svg">

      <circle cx="100" cy="100" r="80" id="green-halo" fill="none" stroke="#00CC33" stroke-width="23"
        stroke-dasharray="0,20000" transform="rotate(-95,100,100)" />

    </svg>

    <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1"
      viewBox="0 0 200 200" preserveAspectRatio="none" class="circle_svg2">

      <circle cx="100" cy="100" r="80" id="green-halo2" fill="none" stroke="#00CC33" stroke-width="3"
        stroke-dasharray="0,20000" transform="rotate(-95,100,100)" />

    </svg>


setTimeout(drawCircle, 1500);
setTimeout(drawCircle2, 1500);

function drawCircle() {
 var circle = document.getElementById('green-halo');
 var interval = 30;
 var angle = 0;
 var angle_increment = 6;
 var max_angle = 384;

 window.timer = window.setInterval(function () {
   circle.setAttribute("stroke-dasharray", angle + ", 20000");
   circle.setAttribute("stroke", "rgb(255, 255, 255)");

   if (angle >= max_angle) {
     window.clearInterval(window.timer);
   }
   angle += angle_increment;
 }.bind(this), interval);
 setTimeout(removeCirclePartAnimation, 2200);
}

function drawCircle2() {
  var circle1 = document.getElementById('green-halo2');
  var interval1 = 30;
  var angle1 = 0;
  var angle_increment1 = 6;
  var max_angle1 = 384;

  window.timer = window.setInterval(function () {
  circle1.setAttribute("stroke-dasharray", angle1 + ", 20000");
  circle1.setAttribute("stroke", "rgb(255, 255, 255)");

  if (angle1 >= max_angle1) {
    window.clearInterval(window.timer);
  }
  angle1 += angle_increment1;
}.bind(this), interval1);

} 

I have the other function like this one but once I add it, they don't behave as they should. Once I disable the second one, the first setTimeout works fine with animation and actions. How can I solve this? Thanks in advance.


Solution

  • Setting a window.variable is the same as creating a global variable, in other words:

    function AFunction() {
        window.timer = 123;
    }
    

    is the same as

    <script>
        var timer = 123;
    </script>
    

    (script tag added to show it's not inside another function)

    So using window.timer for two different timers means you're reusing the same variable and they conflict with each other:

    var timer;
    
    timer = setInterval(...
    timer = setInterval(...
    
    clearInterval(timer);
    clearInterval(timer);
    

    will only clear the 2nd timer as the first one has been lost/overwritten.

    The simple solution is to use two different variables:

    var timer1, timer2;
    
    timer1 = setInterval(...
    timer2 = setInterval(...
    
    clearInterval(timer1);
    clearInterval(timer2);
    

    will clear both timers.


    An alternative is to use let

    function drawCircle() {
        let timer = window.setInterval(function () {
            ...
    
        if (angle >= max_angle) {
            window.clearInterval(timer);
        }
    

    which will restrict the variable named timer inside drawCircle, so you reuse the name "timer" in drawCircle2 and it will be a different variable.