SBB
SBB

Reputation: 8970

javascript timer implement pause function

I have a javascript / jquery timer that I have been working on and up until this point I have only needed to start and reset the timer. I now need to add a function in to pause it and I am not sure how to go about doing so.

I was able to pause the timer by clearing the interval but now I need to figure out how to resume it when clicking start again which is where my problem is.

I tried passing the interval back to the function but that didn't seem to help.

Any thoughts?

JS Fiddle: https://jsfiddle.net/3dweffy8/3/

// Define a global so we can clear it in our reset
var interval;

(function($) {

  // Define our plugins vars if they were not set
  $.fn.upCount = function(options, callback) {
    var settings = $.extend({
      startTime: null,
      offset: null,
      reset: null,
      resume: null
    }, options);

    // Save container
    var container = this,
      globalContainer = container.parent().html();

    // get the current date
    var currentDate = function() {
      var date = new Date();
      return date;
    };

    // Define some global vars
    var original_date = currentDate();
    var target_date = new Date('12/31/2030 12:00:00'); // Count up to this date

    // Are we resetting our counter?
    if (settings.reset) {
      return reset();
    }

    // Do we need to start our counter at a certain time if we left and came back?
    if (settings.startTime) {
      resumeTimer(newDate);
    }

    // Lets resume from where we paused
    if (settings.resume) {
      // not sure how to continue from where we paused...
    }

    // Are we pausing the timer?
    if (settings.pause) {
      return clearInterval(interval);
    }

    // Reset the counter by destroying the element it was bound to
    function reset() {
      var timerContainer = $('[name=timerContainer]');
      timerContainer.empty().append(globalContainer).find('.time').empty().append('00');
      clearInterval(interval);
    }

    // Given a start time, lets set the timer
    function resumeTimer(startTime) {
      original_date = startTime;
    }

    // Start the counter
    function countUp() {

      // Set our current date
      var current_date = currentDate();

      // difference of dates
      var difference = current_date - original_date;

      if (current_date >= target_date) {
        // stop timer
        clearInterval(interval);
        if (callback && typeof callback === 'function') callback();
        return;
      }

      // basic math variables
      var _second = 1000,
        _minute = _second * 60,
        _hour = _minute * 60,
        _day = _hour * 24;

      // calculate dates
      var days = Math.floor(difference / _day),
        hours = Math.floor((difference % _day) / _hour),
        minutes = Math.floor((difference % _hour) / _minute),
        seconds = Math.floor((difference % _minute) / _second);

      // fix dates so that it will show two digets
      days = (String(days).length >= 2) ? days : '0' + days;
      hours = (String(hours).length >= 2) ? hours : '0' + hours;
      minutes = (String(minutes).length >= 2) ? minutes : '0' + minutes;
      seconds = (String(seconds).length >= 2) ? seconds : '0' + seconds;

      // based on the date change the refrence wording
      var ref_days = (days === 1) ? 'day' : 'days',
        ref_hours = (hours === 1) ? 'hour' : 'hours',
        ref_minutes = (minutes === 1) ? 'minute' : 'minutes',
        ref_seconds = (seconds === 1) ? 'second' : 'seconds';

      // set to DOM
      container.find('.days').text(days);
      container.find('.hours').text(hours);
      container.find('.minutes').text(minutes);
      container.find('.seconds').text(seconds);

      container.find('.days_ref').text(ref_days);
      container.find('.hours_ref').text(ref_hours);
      container.find('.minutes_ref').text(ref_minutes);
      container.find('.seconds_ref').text(ref_seconds);

    };

    // start
    interval = setInterval(countUp, 1000);
  };

})(jQuery);

Upvotes: 0

Views: 686

Answers (2)

Hugo Silva
Hugo Silva

Reputation: 6948

The time logic is the least of your problems here. It is quite simple to resolve as it had been pointed out in the comments:

remembering when a timer started, and subtracting it from the time they click pause to get the remaining time

We need to save the elapsed time somehow, in order to subtract from total when we restart. I am going to be using jQuery .data for demonstration purposes. Where you initialise your vars like original_date, add a new var, that should check for previously saved values:

var elapsed_time = container.data('elapsed');

Then, when you calculate the current time difference, make sure you save it back at the same place:

// difference of dates
var difference = (current_date - original_date) + (elapsed_time || 0);
container.data('elapsed', difference);

Have a look at the working fiddle: https://jsfiddle.net/3dweffy8/13/


With that said, I want to mention that you have some weird pattern going on there. It looks like a jQuery plugin, but not really. It doesn't hold any state. It has this strange mapping of settings to functions. Maybe you should just make it plain functions. Or dive deep into plugin architecture - https://learn.jquery.com/plugins/advanced-plugin-concepts/

Try creating an instance, so you are able to save data and attach methods. As a rule of thumb for a decent plugin, you should be able to have several instances, in your case several timers, running independently on the page.

Upvotes: 1

Ismail RBOUH
Ismail RBOUH

Reputation: 10450

Simply, you can save the difference between the original date and current date globally, and when you call resume you must subtract the global difference from the original date which will be set to current date:

if (settings.resume) {
    original_date.setTime(original_date.getTime() - lastDiff);
    interval = setInterval(countUp, 1000);
    return;
}

Demo: https://jsfiddle.net/o6rm1s4x/

Upvotes: 0

Related Questions