javascript bug using setTimeout() - javascript

I have this program which tells you your reaction time, and it works fine, but if you run the program and click the start button twice, instead of once, the background turns red right away, instead of waiting for the set interval. Thanks in advance to anyone that can help.
<!DOCTYPE html>
<html>
<head>
<script>
var button = document.getElementById("reactionTester");
var start = document.getElementById("start");
var startTime;
var scoreContainer = document.getElementById("p");
var css = document.createElement("style");
css.type = "text/css";
var counter = 0;
function init() {
var startInterval /*in milliseconds*/ = Math.floor(Math.random() * 10) * 1000;
setTimeout(startTimer, startInterval);
}
function startTimer() {
startTime = Date.now();
document.body.appendChild(css);
css.innerHTML = "html{background-color: red;}";
if (counter = 1) {
p1 = document.getElementsByTagName('p')[0];
p1.parentNode.removeChild(p1);
}
}
function stopTimer() {
if (startTime) {
var stopTime = Date.now();
var dif = stopTime - startTime;
alert("Your time is " + dif + " ms");
startTime = null;
css.innerHTML = null;
var p = document.createElement("p");
document.body.appendChild(p);
p.innerHTML = dif;
counter = 0;
counter++;
} else {
alert("don't trick me");
}
}
</script>
</head>
<body>
<form id="form">
<div class="tableRow">
<input type="button" value="start" id="start" onclick="init()">
</div>
<div class="tableRow">
<input type="button" id="reactionTester" onclick="stopTimer()" value="stop">
</div>
<div id="p">
</div>
</form>
</body>
</html>

There are 2 (potential) problems here:
Every time init() is run it resets startTime to Date.now(). So when stopTimer runs, it runs only against the latest click time.
init can set an interval of 0ms which may be intended...
To fix the first problem you can do one of a few things, but the most straightforward is to cancel the first timeout by getting a reference then later clearing it:
var timeoutId;
function init(){
if (timeout) clearTimeout(timeoutId);
timeoutId = setTimeout(func, delay);
}

You need to keep track of the timers in a variable so you can reset it.
<!DOCTYPE html>
<html>
<head>
<script>
var button = document.getElementById("reactionTester");
var start = document.getElementById("start");
var startTime;
var scoreContainer = document.getElementById("p");
var css = document.createElement("style");
css.type = "text/css";
var counter = 0;
var timer = null;
function init() {
var startInterval /*in milliseconds*/ = Math.floor(Math.random() * 10) * 1000;
clearTimeout(timer);
timer = setTimeout(startTimer, startInterval);
}
function startTimer() {
startTime = Date.now();
document.body.appendChild(css);
css.innerHTML = "html{background-color: red;}";
if (counter = 1) {
p1 = document.getElementsByTagName('p')[0];
p1.parentNode.removeChild(p1);
}
}
function stopTimer() {
if (startTime) {
var stopTime = Date.now();
var dif = stopTime - startTime;
alert("Your time is " + dif + " ms");
startTime = null;
css.innerHTML = null;
var p = document.createElement("p");
document.body.appendChild(p);
p.innerHTML = dif;
counter = 0;
counter++;
} else {
alert("don't trick me");
}
}
</script>
</head>
<body>
<form id="form">
<div class="tableRow">
<input type="button" value="start" id="start" onclick="init()">
</div>
<div class="tableRow">
<input type="button" id="reactionTester" onclick="stopTimer()" value="stop">
</div>
<div id="p">
</div>
</form>
</body>
</html>

Related

How to get a working countdown timer with a button that adds +1 to a counter after every click

I am setting up a project for class which I need to use jquery. I have settled on a project whereby you would click the button, the counter would increase by one and a timer would start. This would act like a game to see how fast you can click in 10 seconds.
$("#button").mousedown(function () {
score = score + 1;
startTimer();
});
function startTimer() {
if (stop === 0) {
stop = stop + 1;
var counter = 0;
var interval = setInterval(function () {
counter++;
display = 60 - counter;
$("#button").html("Click! (" + display + " secs)");
if (counter == 60) {
alert("Times up!");
clearInterval(interval);
stop = 0;
endscore = score;
score = 0;
}
}, 1000);
}
};
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="clicks">
<p><span>0</span></p>
</div>
<div class="boxtext">
<p>Time Remaining: <span>10</span> Seconds </p>
</div>
<div class="but">
<button type="button" name="button">Click</button>
</div>
I expected the timer to start and the counter to increase by one but nothing happens at all.
You need to:
Add an id to your button:
<button id="button" type="button" name="button">Click</button>
Also you need to define the score & stop variables globally outside the function:
var score = 0;
var stop = 0;
<!DOCTYPE html>
<html>
<head>
<script
src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js">
</script>
<script>
$(document).ready(function(){
var score=0;
var stop=0;
var counter = 0;
var endscore=0;
$("button").mousedown(function () {
score = score + 1;
$("#score").text(score);
startTimer();
});
function startTimer() {
if (stop === 0) {
stop = stop + 1;
var interval = setInterval(function () {
counter++;
display = 60 - counter;
// $("button").html("Click! (" + display + " secs)");
if (counter == 60) {
alert("Times up!");
clearInterval(interval);
stop = 0;
endscore = score;
score = 0;
}
$('#timeRemaining').text(display);
}, 1000);
}
};
});
</script>
</head>
<body>
<div class="clicks">
<p><span id="score">0</span></p>
</div>
<div class="boxtext">
<p>Time Remaining: <span id="timeRemaining">60</span> Seconds </p>
</div>
<div class="but">
<button type="button" name="button">Click</button>
</div>
</body>
</html>
You're using as selector an ID, however your button element doesn't have that ID. You can do the following:
Add the id to that button.
Or, you can change the selector as:
$(".but").mousedown(function() { // or $('button[name="button"]').mousedown(function() {...});
score = score + 1;
startTimer();
});
From your html you didn't have id="button" so use name selector or assign id to the button.
Like below.
$("input[name='button']").mousedown(function() {
score = score + 1;
startTimer();
});
You forgot to initialize some variables and give some ids.
var score = 0
var stop = 0
$("#button").click(function () {
score = score + 1;
startTimer();
});
function startTimer() {
console.log('start timer')
if (stop === 0) {
stop = stop + 1;
var counter = 0;
var interval = setInterval(function () {
console.log('#interval')
counter++;
display = 60 - counter;
$("#button").html("Click! (" + display + " secs)");
if (counter == 60) {
alert("Times up!");
clearInterval(interval);
stop = 0;
endscore = score;
score = 0;
}
$('#counter').html(counter)
}, 1000);
}
};
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="clicks">
<p><span id="counter">0</span></p>
</div>
<div class="boxtext">
<p>Time Remaining: <span>10</span> Seconds </p>
</div>
</div>
<div class="but">
<button type="button" id="button">Click</button>
</div>

Adding Start, Stop, Reset button for timer

I have this count-up timer code and want to add start, stop and reset button. It start right at the page load.
<script type="text/javascript">
var timerVar = setInterval(countTimer, 1000);
var totalSeconds = 0;
function countTimer() {
++totalSeconds;
var hour = Math.floor(totalSeconds /3600);
var minute = Math.floor((totalSeconds - hour*3600)/60);
var seconds = totalSeconds - (hour*3600 + minute*60);
document.getElementById("hour").innerHTML =hour;
document.getElementById("minute").innerHTML =minute;
document.getElementById("seconds").innerHTML =seconds;
}
</script>
It's just some simple manipulation of hour, minute and seconds and making use of clearInterval and setInterval. In my snipper, reset won't stop the timer, but it's easy to make that happen by a few lines of code.
window.onload = () => {
let hour = 0;
let minute = 0;
let seconds = 0;
let totalSeconds = 0;
let intervalId = null;
function startTimer() {
++totalSeconds;
hour = Math.floor(totalSeconds /3600);
minute = Math.floor((totalSeconds - hour*3600)/60);
seconds = totalSeconds - (hour*3600 + minute*60);
document.getElementById("hour").innerHTML =hour;
document.getElementById("minute").innerHTML =minute;
document.getElementById("seconds").innerHTML =seconds;
}
document.getElementById('start-btn').addEventListener('click', () => {
intervalId = setInterval(startTimer, 1000);
})
document.getElementById('stop-btn').addEventListener('click', () => {
if (intervalId)
clearInterval(intervalId);
});
document.getElementById('reset-btn').addEventListener('click', () => {
totalSeconds = 0;
document.getElementById("hour").innerHTML = '0';
document.getElementById("minute").innerHTML = '0';
document.getElementById("seconds").innerHTML = '0';
});
}
<div>Hour: <span id="hour"></span></div>
<div>Minute: <span id="minute"></span></div>
<div>Second: <span id="seconds"></span></div>
<button id="start-btn">Start</button>
<button id="stop-btn">Stop</button>
<button id="reset-btn">Reset</button>
Duplicate of Adding start, stop, and reset buttons for a timer
but just because there is not the HTML part, there is the full answer (html + js thanks to #closure )
(function() {
"use strict";
var secondsLabel = document.getElementById('seconds'),
minutesLabel = document.getElementById('minutes'),
hoursLabel = document.getElementById('hours'), totalSeconds = 0,
startButton = document.getElementById('start'),
stopButton = document.getElementById('stop'),
resetButton = document.getElementById('reset'), timer = null;
startButton.onclick = function() {
if (!timer) {
timer = setInterval(setTime, 1000);
}
};
stopButton.onclick = function() {
if (timer) {
clearInterval(timer);
timer = null;
}
};
resetButton.onclick = function() {
if (timer) {
totalSeconds = 0;
stop();
}
};
function setTime() {
totalSeconds++;
secondsLabel.innerHTML = pad(totalSeconds % 60);
minutesLabel.innerHTML = pad(parseInt(totalSeconds / 60));
hoursLabel.innerHTML = pad(parseInt(totalSeconds / 3600))
}
function pad(val) {
var valString = val + "";
if (valString.length < 2) {
return "0" + valString;
} else {
return valString;
}
}
})();
<p id='seconds'></p>
<p id='minutes'></p>
<p id='hours'></p>
<button id='start'>start</button>
<button id='stop'>stop</button>
<button id='reset'>reset</button>
//DOM CACHE
const startBtn = document.querySelector("#start-btn")
const stopBtn = document.querySelector("#stop-btn")
const resetBtn = document.querySelector("#reset-btn")
var minDigits = document.getElementById("min");
var secDigits = document.getElementById("sec");
//INITIALIZING VARIABLES
var hrs = 0;
var mins = 0;
var secs = 0;
var countSec = 0;
var timerVar = null;
//FUNCTIONS=============
function startCounter() {
++countSec;
hrs = Math.floor(countSec /3600);
mins = Math.floor((countSec - hrs*3600)/60);
secs = countSec - (hrs*3600 + mins*60);
if (secs < 10) {
secDigits.innerHTML = "0" + secs;
} else { secDigits.innerHTML = secs; }
minDigits.innerHTML = "0" + mins;
}
startBtn.addEventListener('click', () => {
timerVar = setInterval(startCounter, 1000);
})
stopBtn.addEventListener('click', () => {
if (timerVar)
clearInterval(timerVar);
});
resetBtn.addEventListener('click', () => {
countSec = 0;
secDigits.innerHTML = "00";
minDigits.innerHTML = "00";
clearInterval(timerVar);
});
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="style.css">
<title>Clock JS</title>
</head>
<body>
<div class="container">
<header>
<h1>SIMPLE COUNTER</h1>
<p>At A Time No Time To Check Time</p>
</header>
<div class="clock-face">
<div class="digital-time"></div>
<div class="greeting"></div>
<div class="screen">
<h1 class="digits">
<span id="min" class="minutes">00</span>:<span id="sec" class="seconds">00</span>
</h1>
</div>
<div class="clock-dial">
<button id="start-btn">start</button>
<button id="stop-btn">stop</button>
<button id="reset-btn">reset</button>
</div>
</div>
</div>
<script src="app.js" charset="utf-8"></script>
</body>
</html>

Want to create a program that gives a set time (stopwatch) and generates keys within that time all using the same button

I am working on a project that generates a 6 digit string key all the while being timed. So my stopwatch has 3 buttons. Start, stop, and reset. I want to create a program in which, when i click on start it will generate a key and the stopwatch will run. So i want to know how i can have the button execute two actions at once. Same with stop, and reset will generate a new key. Also how can i put these two codes together into one?
My code for key generator:
function Keygenerate() {
var text ="";
var possible = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"
for(var i=0; i < 5; i++ ){
text += possible.charAt(Math.floor(Math.random() * possible.length()));
}
return text;
}
My code for the Stopwatch:
<div class="class">
<p>CSC 131 Attendance Tracker</p>
</div>
<div class="stopwatch">
<div class="title">
<h2>KEY:</h2>
</div>
<div class="key">
<input type="text" name="output">
</div>
<div class="time">
<h2>TIME:</h2>
</div>
<div class="display">
<span class="minutes">00:</span><span class="seconds">00:</span><span class="centiseconds">00</span>
</div>
<div class="controls">
<button class="start">Start</button>
<button class="stop">Stop</button>
<button class="reset">Reset</button>
</div>
</div>
<script>
var ss = document.getElementsByClassName('stopwatch');
[].forEach.call(ss, function (s) {
var currentTimer = 0,
interval = 0,
lastUpdateTime = new Date().getTime(),
start = s.querySelector('button.start'),
stop = s.querySelector('button.stop'),
reset = s.querySelector('button.reset'),
mins = s.querySelector('span.minutes'),
secs = s.querySelector('span.seconds'),
cents = s.querySelector('span.centiseconds');
start.addEventListener('click', startTimer);
stop.addEventListener('click', stopTimer);
reset.addEventListener('click', resetTimer);
function pad (n) {
return ('00' + n).substr(-2);
}
function update () {
var now = new Date().getTime(),
dt = now - lastUpdateTime;
currentTimer += dt;
var time = new Date(currentTimer);
mins.innerHTML = pad(time.getMinutes()) + ":";
secs.innerHTML = pad(time.getSeconds()) + ":";
cents.innerHTML = pad(Math.floor(time.getMilliseconds() / 10));
lastUpdateTime = now;
if(now == time.getMinutes()){
clearInterval(interval);
}
}
function startTimer () {
if (!interval) {
lastUpdateTime = new Date().getTime();
interval = setInterval(update, 1);
}
}
function stopTimer () {
clearInterval(interval);
interval = 0;
}
function resetTimer () {
stopTimer();
currentTimer = 0;
mins.innerHTML = secs.innerHTML = cents.innerHTML = pad(0);
}
});
</script>
</body>
Well, at its basic you would do it by attaching two functions to an event:
<button onclick = "generate_key(); stopwatch_run();">
You can also attach functions to a click event:
object.addEventListener("click", function(){ ... });
It seems like what you're asking is very basic, so I am not sure if I'm being helpful.

How to check how long you hover an element in pure javascript?

I want to show a tootip when an element is hovered for 2 seconds or more. How can I do it?
var startTime, endTime;
function handlerIn() {
startTime = new Date();
}
function handlerOut() {
endTime = new Date();
var timeDiff = endTime - startTime; //in ms
// strip the ms
timeDiff /= 1000;
// get seconds
var seconds = Math.round(timeDiff % 60);
console.log("hover during " + seconds + " sec");
}
.hover {
background-color: red;
width: 100px;
height: 100px;
}
<div class="hover" onmouseenter="handlerIn()" onmouseleave="handlerOut()">HOVER ME</div>
<div id="seconds"></div>
You can check the enter time and exit time with onmouseenter="fn()" and onmouseout="fn()". Here's a simple way to do it and it also displays the time in miliseconds!
var time = 0;
var hover = 0;
var out = 0;
function getInTime() {
hover = Date.now();
}
function getOutTime() {
out = Date.now();
time = out-hover;
document.getElementById('time').innerHTML = " Show hover time: " + time + 'ms';
}
<button onmouseout="getOutTime()" onmouseenter="getInTime()" >Hover Here</button>
<br /><br />
<button id="time">Hover Time</button>
You can use setTimeout() method with onmouseover and onmouseout events.
Tooltip css:
http://www.w3schools.com/howto/howto_css_tooltip.asp
setTimeout method: http://www.w3schools.com/jsref/met_win_settimeout.asp
<div id="example" class="tooltip" onmouseover="start()" onmouseout="stop()">example text</div>
let t, hoverTime=2000;
function start(){
t = setTimeout('showTooltip()', hoverTime);
}
function showTooltip(){
let node = document.createElement("span");
let textnode = document.createTextNode("Tooltip text");
node.className='tooltiptext';
node.appendChild(textnode);
document.getElementById("example").appendChild(node);
}
function stop(){
clearTimeout(t);
if(document.getElementById("example").childNodes[1]){
document.getElementById("example").removeChild(document.getElementById("example").childNodes[1]);
}
}

Why can't I see the countdown timer

I tried to make a countdown timer using setInterval(). I used code made by other people to learn how, but it failed. After searching to find the issue, I was not able to find it.
My code:
<!DOCTYPE html>
<html>
<head>
<title>Count</title>
<script="text/javascript">
var Stime = 10; //Set time(minute)
var Ssecond = Stime * 60;
var countdownID=0;
function inidown(){
countdownID = setInterval("Count()",1000);
}
function Count(){
if(Ssecond>0){
var rM=Ssecond/60;
var rS=Ssecond%60;
document.getElementById("count").innerHTML=rM+":"+rS;
Ssecond--;
}
else{
clearInterval(countdownID);
document.getElementById("out").innerHTML="time out";
}
}
</script>
</head>
<body onload="inidown()">
<div id="count"></div>
<div id="out"></div>
</body>
</html>
I saw that code on http://blog.niklasottosson.com/?p=665
var Stime = 10; //?? ??(?)
var Ssecond = Stime * 60;
var countdownID = 0;
function inidown() {
countdownID = setInterval("Count()", 1000);
}
function Count() {
if (Ssecond > 0) {
var rM = Ssecond / 60;
var rS = Ssecond % 60;
document.getElementById("count").innerHTML = rM + ":" + rS;
Ssecond--;
} else {
clearInterval(countdownID);
DivCount.innerHTML = "Time Out";
document.getElementById("out").innerHTML = "time out";
}
}
No error occurs in that code.
There was a problem with your script tag.
Use Math.floor for your minutes.
Pad the seconds for single digits.
<html>
<head>
<title>Count</title>
<script type="text/javascript">
var Stime = 10; //Set time(minute)
var Ssecond = Stime * 60;
var countdownID = 0;
function inidown() {
countdownID = setInterval("Count()", 1000);
}
function Count() {
if (Ssecond > 0) {
var rM = Math.floor(Ssecond / 60);
var rS = ("0" + (Ssecond % 60)).slice(-2);
document.getElementById("count").innerHTML = rM + ":" + rS;
Ssecond--;
} else {
clearInterval(countdownID);
document.getElementById("count").innerHTML = "";
document.getElementById("out").innerHTML = "Time Out";
}
}
</script>
</head>
<body onload="inidown()">
<div id="count"></div>
<div id="out"></div>
</body>
</html>
<script="text/javascript"> should have a type attribute <script type="text/javascript">
setInterval("Count()",1000); works, but can also be rewritten as setInterval(Count,1000);
With these changes it is working.

Categories