Reputation: 8970
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
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
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