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