.blur() causes my stopwatch to lag pretty significantly - javascript

Hi I have a stopwatch here that works pretty great except that I wanted to add .blur() method to the buttons so that when I click them, the space bar doesn't re-trigger a button when it is pressed.
I got this idea from a bpm counter I was making that integrated the stopwatch and where the space bar thing was a much bigger issue.
I'm just curious, why does simply adding .blur() to my event listener cause the stopwatch to noticeably lag when hitting start/stop? Is there a better alternative I could be using instead? Will this method negatively affect my bpm counter as well? Am I using .blur() correctly?
This is my first post on Stack Overflow so please let me know if I formatted this question wrong in any way.
// initialize variables
const STARTSTOP = document.querySelector('.start-stop');
const RESET = document.querySelector('.reset');
const STOPWATCH = document.querySelector('.stopwatch');
const DISPLAY = document.querySelector('.display');
let stopwatchIsActive = false;
let elapsedTime = 0;
var myInterval;
// stopwatch functions
function convertElapsedTimeToString() {
let milliseconds = Math.floor((elapsedTime % 1000) / 10),
seconds = Math.floor((elapsedTime / 1000) % 60),
minutes = Math.floor((elapsedTime / (1000 * 60)) % 60),
hours = Math.floor((elapsedTime / (1000 * 60 * 60)) % 24);
minutes = (minutes < 10) ? "0" + minutes : minutes;
seconds = (seconds < 10) ? "0" + seconds : seconds;
milliseconds = (milliseconds < 10) ? "0" + milliseconds : milliseconds;
STOPWATCH.innerHTML = minutes + ":" + seconds + ":" + milliseconds;
if (hours >= 1) {
hours = (hours < 10) ? "0" + hours : hours;
STOPWATCH.innerHTML = hours + ":" + minutes + ":" + seconds;
};
}
function resetStopwatch() {
STOPWATCH.innerHTML = "00:00:00";
stopwatchIsActive = false;
elapsedTime = 0;
clearInterval(myInterval);
};
function startStopStopwatch() {
if (stopwatchIsActive) {
clearInterval(myInterval);
convertElapsedTimeToString();
stopwatchIsActive = false;
} else if (elapsedTime > 0) {
startTime = Date.now() - elapsedTime;
clearInterval(myInterval);
myInterval = setInterval(function() {
elapsedTime = Date.now() - startTime;
convertElapsedTimeToString();
}, 10);
stopwatchIsActive = true;
} else {
startTime = Date.now();
myInterval = setInterval(function() {
elapsedTime = Date.now() - startTime;
convertElapsedTimeToString();
}, 10);
stopwatchIsActive = true;
}
};
// executes stopwatch functions
RESET.addEventListener("click", () => {
resetStopwatch();
RESET.blur();
});
STARTSTOP.addEventListener("click", () => {
startStopStopwatch();
STARTSTOP.blur();
});
DISPLAY.addEventListener("click", () => {
startStopStopwatch();
});
<div class="container">
<header class="header">This is a Stopwatch.</header>
<div class="display">
<h2 class="stopwatch">00:00:00</h2>
</div>
<div class="stats">
<button class="start-stop">Start/Stop</button>
</div>
<button class="reset">RESET</button>
</div>

Related

Countdown It does not Work with click button

I have a simple question. I want to make this code work with the Reset time button when the time is start again from 30 min delete the ( You are Ready! ) and start the time
var seconds = 30;
function secondPassed() {
var minutes = Math.round((seconds - 30) / 60);
var remainingSeconds = seconds % 60;
if (remainingSeconds < 10) {
remainingSeconds = "0" + remainingSeconds;
}
document.getElementById('countdown').innerHTML = minutes + ":" + remainingSeconds;
if (seconds == 0) {
clearInterval(countdownTimer);
document.getElementById('countdown').innerHTML = "You are Ready!";
} else {
seconds--;
}
}
var countdownTimer = setInterval('secondPassed()', 1000);
<span id="countdown" class="timer">
Reset time
I created a new function to reset the seconds and restart the timer and linked it to the button. I have also isolated at the start of the js code the variables that will count the seconds and hold the reference to the Interval.
is this what you are looking for?
var seconds;
var countdownTimer;
function startTimer() {
if (!seconds || seconds == 0) {
seconds = 30;
clearInterval(countdownTimer);
countdownTimer = setInterval(secondPassed, 1000)
secondPassed();
}
}
function secondPassed() {
var minutes = Math.round((seconds - 30) / 60);
var remainingSeconds = seconds % 60;
if (remainingSeconds < 10) {
remainingSeconds = "0" + remainingSeconds;
}
document.getElementById('countdown').innerHTML = minutes + ":" + remainingSeconds;
if (seconds == 0) {
clearInterval(countdownTimer);
document.getElementById('countdown').innerHTML = "You are Ready!";
} else {
seconds--;
}
}
startTimer();
<html>
<body>
<div>
<span id="countdown" class="timer"></span>
</div>
Reset time
</body>
</html>
Here create a separate function where after clicking - it disables the button, sets the timer, and changes button text.
In secondPassed method, if seconds == 0, it enables the button, so that you can start count down again.
var seconds = 30;
var countdownTimer;
function secondPassed() {
var minutes = Math.round((seconds - 30) / 60);
var remainingSeconds = seconds % 60;
if (remainingSeconds < 10) {
remainingSeconds = "0" + remainingSeconds;
}
document.getElementById('countdown').innerHTML = minutes + ":" + remainingSeconds;
if (seconds == 0)
{
clearInterval(countdownTimer);
document.getElementById('reset').disabled = false;
document.getElementById('countdown').innerHTML = "You are Ready!";
} else
{
seconds--;
}
}
function start(){
seconds = 30;
document.getElementById('reset').innerHTML = "Reset";
document.getElementById('reset').disabled = true;
countdownTimer = setInterval('secondPassed()', 1000);
}
//on load call
start();
<div>
<span id="countdown" class="timer"/>
</div>
<button id="reset" onclick="start()">
Start
</button>
Let's assume something quite basic, like the following:
<div>00:00</div>
<button>Reset</button>
Below is an approach you could take, fully-commented.
// We'll start by getting a couple element references
const label = document.querySelector("div");
const button = document.querySelector("button");
// Next, we'll bind-up the click handler for the button
button.addEventListener("click", () => {
// When the user clicks the button, we'll set the time
// limit to 30 minutes and proceed
let timer = 60 * 30;
// Disable the button to prevent further clicks
button.disabled = true;
button.dataset.default = button.textContent;
button.textContent = "Now counting down!";
// Let's setup some code that will be executed every second
button.interval = setInterval(() => {
// This decimal will be a number like 29.9521
const decimal = timer / 60;
// We'll convert 29.9521 into 29, for 29 minutes
const wholeMinute = Math.floor(decimal);
// Next, we'll take the .9521 and multiply by 60 for seconds
const wholeSecond = Math.round(60 * (decimal - wholeMinute));
// We'll pad both of the numbers so they always have a leading 0
const lblMin = wholeMinute.toString().padStart(2, 0);
const lblSec = wholeSecond.toString().padStart(2, 0);
// As long as we aren't out of seconds
if (timer >= 0) {
// Reduce the timer by 1 second
timer = timer - 1;
// And print the new label on our label element
label.textContent = `${ lblMin }:${ lblSec }`;
// Then return, so we don't execute what comes next
return;
}
// If we made it this far, our timer ran out
// Start by enabling the button
button.disabled = false;
// Restore the original text of the button
button.textContent = button.dataset.default;
// And clear our interval, as it is no longer needed
clearInterval(button.interval);
// Our interval will 'tick' once every second (1000 milliseconds)
}, 1000);
});

Make Countdown Timer 2 Digits For HH:MM:SS [duplicate]

This question already has answers here:
How can I pad a value with leading zeros?
(76 answers)
Closed 2 years ago.
So, I am a novice in Javascript and I am wondering if someone can help me with this. I believe this question is really really easy for most. Well, this is a countdown timer with select options to set up the time. It is working well. The problem is that, when the countdown starts, I want the single digit numbers to show the number zero first. Basically, I want the numbers for HH:MM:SS to be 2 digits. For example, 00:01:59 and not 0:1:59. I believe it has something to do with padString or something (I could be wrong), but my proficiency is still no that advanced.
Note: I would highly appreciate it if we can come up with a Vanilla Javascript solution and not JQuery simply because I want to use this offline and without any online dependencies. Thank you in advance.
Javascript
<script>
var hours = 0;
var minutes = 0;
var seconds = 0;
var interval = null;
document.getElementById('hours').addEventListener('change', e => {
hours = +e.target.value;
});
document.getElementById('minutes').addEventListener('change', e => {
minutes = +e.target.value;
});
document.getElementById('seconds').addEventListener('change', e => {
seconds = +e.target.value;
});
document.getElementById('startTimer').addEventListener('click', () => {
var timeInSeconds = (hours * 60 * 60) +
(minutes * 60) +
seconds;
const audio = new Audio("audioURL.mp3");
var displayTime = () => {
var displayHours = Math.floor(timeInSeconds / (60 * 60));
var remainder = timeInSeconds - (displayHours * 60 * 60);
var displayMinutes = Math.floor(remainder / 60);
var displaySeconds = remainder - (displayMinutes * 60);
document.getElementById("timer").innerHTML = displayHours + ":" +
displayMinutes + ":" + displaySeconds;
};
interval = setInterval(() => {
displayTime();
timeInSeconds -= 1;
if (timeInSeconds < 0) {
clearInterval(interval);
audio.play();
}
}, 1000);
});
</script>
You could use ('0' + myValue).substr(-2) to fix the length with 2 characters. In this case '01' would be stay as '01' and '012' will be '12' because the -2 will cut the string from the end. Then your code will be:
var hours = 00;
var minutes = 00;
var seconds = 00;
var interval = null;
document.getElementById('hours').addEventListener('change', e => {
hours = +e.target.value;
});
document.getElementById('minutes').addEventListener('change', e => {
minutes = +e.target.value;
});
document.getElementById('seconds').addEventListener('change', e => {
seconds = +e.target.value;
});
document.getElementById('startTimer').addEventListener('click', () => {
var timeInSeconds = (hours * 60 * 60) +
(minutes * 60) +
seconds;
const audio = new Audio("audioURL.mp3");
var displayTime = () => {
var displayHours = Math.floor(timeInSeconds / (60 * 60));
var remainder = timeInSeconds - (displayHours * 60 * 60);
var displayMinutes = Math.floor(remainder / 60);
var displaySeconds = remainder - (displayMinutes * 60);
document.getElementById("timer").innerHTML = ('0' + displayHours).substr(-2) + ":" +
('0' + displayMinutes).substr(-2) + ":" + ('0' + displaySeconds).substr(-2);
};
interval = setInterval(() => {
displayTime();
timeInSeconds -= 1;
if (timeInSeconds < 0) {
clearInterval(interval);
audio.play();
}
}, 1000);
});

I want to add multiple timers on different parts of my django webpage using javascript

I am creating a website in which there are various campaigns.
User can set timer to this campaigns.
There is a webpage in which all campaigns are listed in table.
And I want to show a timer for every campaign in that particular table using JavaScript.
I have created a JavaScript function which takes a timeout and starts a timer but I want to show multiple timers at once.
Thank you.
Not long ago I also needed multiple timers in the same page, so I created a simple interval sync tool. The main goal is to move all timers with only one interval and save CPU.
You can check it here -> https://ilian6806.github.io/Ticker/.
Also, if you are using jQuery, you can use it as a plugin.
(function () {
function secondsToTime(sec, colonBlinking) {
sec = parseInt(sec, 10);
if (sec <= 0) {
return '00:00:00';
}
var days = Math.floor(sec / 86400);
var hours = Math.floor((sec - days * 86400) / 3600);
var minutes = Math.floor((sec - (hours * 3600) - (days * 86400)) / 60);
var seconds = sec - (days * 86400) - (hours * 3600) - (minutes * 60);
if (days > 0) { hours += (days * 24); }
if (hours < 10) { hours = '0' + hours; }
if (minutes < 10) { minutes = '0' + minutes; }
if (seconds < 10) { seconds = '0' + seconds; }
return hours + ':' + minutes + ':' + seconds;
}
$.fn.timer = function (ticker, time, callback) {
if (!window.Ticker || !(ticker instanceof Ticker)) {
return this;
}
var that = this;
var currTickId = parseInt(this.data('jqTimerInterval'));
if (currTickId) {
ticker.clear(currTickId);
}
that.html(secondsToTime(time));
var tickId = ticker.set(function () {
time--;
that.html(secondsToTime(time));
if (time < 0) {
ticker.clear(tickId);
if ($.isFunction(callback)) {
callback();
}
}
});
this.data('jqTimerInterval', tickId);
this.addClass('jq-timer');
return this;
};
$.fn.clearTimers = function () {
this.find('.jq-timer').each(function () {
var currInterval = $(this).data('jqTimerInterval');
if (currInterval) {
clearInterval(currInterval);
}
});
return this;
};
})();
Usage:
var ticker = new Ticker(1000); // This is the default value
$('#your-selector').timer(ticker, 3600 function() {
console.log('Done.');
});

How can I make a timer subtract five minutes when a buton is pressed?

I'm making a riddle where people have 45 minutes to find the solution, but I want the timer to go down five minutes when they answer incorrectly to prevent them from just guessing the answer. This is what I have for the timer:
function startTimer(duration, display) {
var start = Date.now(),
diff,
minutes,
seconds;
function timer() {
diff = duration - (((Date.now() - start) / 1000) | 0);
minutes = (diff / 60) | 0;
seconds = (diff % 60) | 0;
minutes = minutes < 10 ? "0" + minutes : minutes;
seconds = seconds < 10 ? "0" + seconds : seconds;
display.textContent = minutes + ":" + seconds;
var cat1 = $("input[#name=Verdachte]:checked");
if (cat1.val() != "2") {
cat1.val("you are right :)");
cat1.attr("disabled", true);
start -= 1000 * 60 * 5;
}
if (diff <= 0) {
start = Date.now() + 1000;
}
};
timer();
setInterval(timer, 1000);
}
window.onload = function() {
var fortyfiveMinutes = 60 * 45,
display = document.querySelector('#time');
startTimer(fortyfiveMinutes, display);
}
But it just keeps subtracting five minutes all the time, so I made a send button for it:
$("#results").click(function() {
if (cat1.val() === "2") {
cat1.val("you are right :)");
cat1.attr("disabled", true);
start -= 1000 * 60 * 5;
}
};
But now the timer just disappears completely, how can I fix this?
try this , I create a new function to check value and set varaibles as globals to access easy ,and change value of 'start' if value of textbox is wrong
var start = Date.now();
function startTimer(duration, display) {
var diff,
minutes,
seconds;
function timer() {
diff = duration - (((Date.now() - start) / 1000) | 0);
minutes = (diff / 60) | 0;
seconds = (diff % 60) | 0;
minutes = minutes < 10 ? "0" + minutes : minutes;
seconds = seconds < 10 ? "0" + seconds : seconds;
display.textContent = minutes + ":" + seconds;
if (diff <= 0) {
start = Date.now() + 1000;
}
};
timer();
setInterval(timer, 1000);
}
window.onload = function() {
var fortyfiveMinutes = 60 * 45,
display = document.querySelector('#time');
startTimer(fortyfiveMinutes, display);
}
function checkValue() {
var cat1 = $("#Verdachte");
if (cat1.val() == "2" || cat1.attr("disabled")) {
cat1.val("you are right :)");
cat1.attr("disabled", true);
} else {
cat1.val("Wrong :(");
start -= 1000 * 60 * 5;
}
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="time"></div>
<input id="Verdachte">
<button onclick="checkValue()"> click me</button>

MomentJS countdown with diff

I am constructing a session timeout as part of a web application using the MomentJS library. What I have so far (below) is the timeToExpire difference (in seconds) from when the user logged in and when the session will expire. However when displaying a countdown clock using setInterval, the diff is NOT recalculated each second and instead the clock is never updated.
Could someone point me in the right direction to what is going wrong?
const access_ttl = 3600;
const now = moment();
const login_timestamp = moment('2017-02-19 17:31:58+00:00');
const expire_timestamp = login_timestamp.add(access_ttl, 's');
const timeToExpire = expire_timestamp.diff(now, 'seconds');
function displayClock(inputSeconds) {
const sec_num = parseInt(inputSeconds.toString(), 10);
const hours = Math.floor(sec_num / 3600);
const minutes = Math.floor((sec_num - (hours * 3600)) / 60);
const seconds = sec_num - (hours * 3600) - (minutes * 60);
let hoursString = '';
let minutesString = '';
let secondsString = '';
hoursString = (hours < 10) ? "0" + hours : hours.toString();
minutesString = (minutes < 10) ? "0" + minutes : minutes.toString();
secondsString = (seconds < 10) ? "0" + seconds : seconds.toString();
return hoursString + ':' + minutesString + ':' + secondsString;
}
function timer() {
$('.output').html(`Expires in: ${displayClock(timeToExpire)}`)
}
setInterval(timer, 1000)
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.17.1/moment.min.js"></script>
<div class="output"></div>
You are not updating the now() or timeToExpire values and so the value you are passing to displayClock is always the same.
Link to complete JS Fiddle: https://jsfiddle.net/xzyjdb1g/2/
var now, timeToExpire;
function updateTime() {
now = moment();
timeToExpire = expire_timestamp.diff(now, 'seconds');
}
function timer() {
updateTime();
$('.output').html(`Expires in: ${displayClock(timeToExpire)}`)
}

Categories

Resources