HiDayurie Dave
HiDayurie Dave

Reputation: 1807

Javascript/jQuery stop the countup timer

I have function countup.

Below is my code and demo.

Now I need to stop the countup but I don't have any idea how to put and do that on function.

So the idea, I just call this: $("#a").countRunTime().stop() then it will stop the countup.

Any idea?

$.fn.countRunTime = function(fromDate){
  var $el = this;

  tick();

  var options = $.extend({
    callback: function() {}
  }, arguments[0] || {});

  options.callback.call(this);

  function formatTime(distance) {
    var hours = Math.floor((distance % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60));
    var minutes = Math.floor((distance % (1000 * 60 * 60)) / (1000 * 60));
    var seconds = Math.floor((distance % (1000 * 60)) / 1000);

    var value = (hours > 9 ? hours : '0' + hours) + ":" +  (minutes > 9 ? minutes : '0' + minutes) + ":" +  (seconds > 9 ? seconds : '0' + seconds);
    return value;
  }

  function tick() {
    var now = new Date().getTime();

    if(fromDate > now) {
      $el.html("Invalid");
    }
    else {
      var remaining = now-fromDate;

      $el.html(formatTime(remaining));
      setTimeout(tick, 1000);
    }
  };
};

$("#a").countRunTime(new Date("20 Jul 2022 11:21:33").getTime());
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="a"></div>

Upvotes: 3

Views: 126

Answers (1)

Ares Stavropoulos
Ares Stavropoulos

Reputation: 170

There is a way to stop the timer by writing $(“#a).countRunTime().stop(). But I don’t necessarily recommend it for the sake of code clarity. The code would look some like this:

$.fn.countRunTime = function(fromDate) {
  var $el = this;
  if (!fromDate) { // If fromDate is undefined
    return {
      stop: () => clearInterval($el.data(“tickInt”))
    };
  }
  var tick = function() {
    var now = new Date().getTime();

    var remaining = now-fromDate;

    $el.html(formatTime(remaining));
  }
  // Code to start timer
  if(fromDate > now) {
    $el.html("Invalid");
    return;
  }
  $el.data(“tickInt”, setInterval(tick, 1000));

  tick();
}

This works by attaching the tickInt to the element do it doesn’t get lost, by using the $.data function. This function, unlike the dataset attribute, allows you to attach objects of elements. When you run countRunTime without a value for fromDate, it returns an obj with the stop function, allowing $(“a”).countRunTime().stop() to work! I only don’t recommend this because attaching for functionality to this function will become very challenging and convoluted. Instead, I recommend countRunTime to be assigned to a JSON obj with keys “start” and “stop”. It should look something like this:

$.fn.countRunTime = function () {
    var $el = this;
    return {
        start: function(fromDate) {

            function formatTime(distance) {
                var hours = Math.floor((distance % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60));
                var minutes = Math.floor((distance % (1000 * 60 * 60)) / (1000 * 60));
                var seconds = Math.floor((distance % (1000 * 60)) / 1000);

                var value = (hours > 9 ? hours : '0' + hours) + ":" +  (minutes > 9 ? minutes : '0' + minutes) + ":" +  (seconds > 9 ? seconds : '0' + seconds);
                return value;
            }

            var tick = function() {
                var now = new Date().getTime();
                var remaining = now-fromDate;
                $el.html(formatTime(remaining));
            }
            // Code to start timer
            var now = new Date().getTime();
            if(fromDate > now) {
                $el.html("Invalid");
                return;
            }
            $el.data("tickInt", setInterval(tick, 1000));
            tick();
        },
        stop: function() {
            clearInterval($el.data("tickInt"))
        }
    }
}

With this code, you can easily expand upon the functionality if needed. It also looks clearer. You can start the timer by typing $("#a").countRunTime().start(new Date("20 Jul 2022 11:21:33").getTime()); and stop it by typing $("#a").countRunTime().stop()

FYI: I nested the JSON obj in a function because I was unsure how else to reference the element by using 'this' without it referencing the JSON obj itself. NOTE: I left out the $.expand function because I honestly have no clue how it works.

Upvotes: 1

Related Questions