Interval stop and reset by clicking another button during an interval

Viewed 113

I want to implement the interval in which the number increases when the button is clicked.

There are multiple buttons and one element with increasing number.

The problem is, if I click another button during an interval, I can't stop the interval that was already in progress.

Please help me.

HTML

<ul> 
  <li><a href="javascript:;" class="btn" data-length="3">1</a></li>
  <li><a href="javascript:;" class="btn" data-length="8">2</a></li>
  <li><a href="javascript:;" class="btn" data-length="5">3</a></li>
</ul>
<div class="counter">0</div>

JS

const interval = (e) => {
  setTimeout(() => { 
    $('.counter').html(e)
  }, 500 * e);
}

$('.btn').on('click', function(){
  var $this = $(this),
      length = $this.data('length');

  for (let i = 1; i <= length; i++) {
    (function(e){
        interval(e)
    })(i)
  }
})

DEMO : https://jsfiddle.net/bnzLrg03/7/

1 Answers

You need setTimeout to a variable and then use clearTimeout to remove the timer from it.

const interval = (e) => {
  window.sT = setTimeout(() => { 
    $('.counter').html(e)
  }, 500 * e);
}

.. and this way you can clear the timer by using clearTimeout(sT)

Piecing all together

const interval = (e) => {
  window.sT = setTimeout(() => { 
    $('.counter').html(e)
  }, 500 * e);
}

$('.btn').on('click', function(){
  if(window.sT) clearTimeout(window.sT);
  var $this = $(this),
      length = $this.data('length');

  for (let i = 1; i <= length; i++) {
    (function(e){
        interval(e)
    })(i)
  }
})

However, I'm really not sure why you are looping over the length value here. I'd suggest using setInterval instead of setTimeout

Updating the solution with a setInterval usage and removed unnecessary variables

const interval = (e) => {
  let i = 1;
  window.sT = setInterval(() => { 
    $('.counter').html(i++)
    if(i > e) clearInterval(sT);
  }, 1000);
}

$('.btn').on('click', function(){
  if(window.sT) clearTimeout(window.sT);
  interval($(this).data('length'))
})

const interval = (e) => {
  let i = 1;
  window.sT = setInterval(() => { 
    $('.counter').html(i++)
    if(i > e) clearInterval(sT);
  }, 1000);
}

$('.btn').on('click', function(){
  if(window.sT) clearTimeout(window.sT);
  interval($(this).data('length'))
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<ul>
  <li><a href="javascript:;" class="btn" data-length="3">1</a></li>
  <li><a href="javascript:;" class="btn" data-length="8">2</a></li>
  <li><a href="javascript:;" class="btn" data-length="5">3</a></li>
</ul>

<div class="counter">0</div>

Related