Simple JavaScript counter function - javascript

I would like to make a counter function, and precise a variable for the starting time and the place to be displayed.
So if I would like to have many counter per page, I can easily manage it:
$(document).ready(function() {
// set time and place (where to display the counter)
function countDown(time, place){
if(time > 0){
time--;
setInterval(function(){countDown(time,place)}, 1000);
} // end if
if(time == 0)
{
window.clearInterval(time);
}
} // end function
$('.click').click(function(){
countDown(30, '#counter');
});
}); // end DOM
</script>
</head>
<body>
<div class="click">clickme</div>
<br />
<div id="counter">30</div>
</body>

Try this:
<html>
<head>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js">
</script>
<script>
var myVar;
var clickcount=0;
function countDown (time, place) {
if (time > 0) {
$(place).html(time);
time--;
myVar=setTimeout(function () { countDown(time, place); }, 1000);
}
}
function startreset(time,place){
clickcount++;
if(clickcount % 2 === 0){
clearTimeout(myVar);
} else {
countDown(time,place);
}
}
$('.click').click(function(){
startreset(30, '#counter');
});
</script>
</head>
<body>
<div class="click" onClick="javascript:countDown(30,'#counter');">clickme</div>
<br />
<div id="counter">30</div>
</body>

The problem you are likely having is that you are calling setInterval multiple times. setInterval does more than just wait the x milliseconds you tell it to and then call your method, it continues to call your method every subsequent x milliseconds. So, when you call countDown the first time, an interval is set for your function. That interval expires and countDown is called again. All fine so far, but now the second call to countDown establishes ANOTHER setInterval. The program will wait your x milliseconds to call countDown from the second setInterval, but it will call it from the first setInterval sooner.
...In other words, you shouldn't be repeatedly calling setInterval. What you want is setTimeout, which waits the specified amount of time and then calls the specified method once.
function countDown (time, place) {
if (time > 0) {
time--;
$(place).html(time);
setTimeout(function () { countDown(time, place); }, 1000);
}
}
Alternatively, if you're not feeling recursive today:
function countDown (time, place) {
var interval = setInterval(function () {
if (time > 0) {
time--;
$(place).html(time);
} else {
window.clearInterval(interval);
}
}, 1000);
}
which leverages setInterval, BUT ONLY ONCE.
JSFiddle provided: http://jsfiddle.net/LKvBR/

Related

Countdown timer jquery on reset it runs faster then time set

I am trying to make a countdown timer where I can change the value of the countdown or rest the countdown but I am not able to clear the last timer so the value of the timer is added again to speed if increased please help me I am also sharing the code.
var sec = $("#timer_this").val();
$("#start").click(function() {
var sec = $("#timer_this").val();
startTimer('start');
});
$("#reset").click(function() {
$("#timer").html(0);
var timex = 0;
clearTimeout(timex);
var timex = 0;
startTimer('start');
});
$("#stop").click(function() {
$("#timer").html($("#timer_this").val());
clearTimeout(timex);
});
function startTimer() {
timex = setInterval(function() {
//document.getElementById('timer').innerHTML = sec + "sec left";
$("#timer").html(sec);
sec--;
if (sec == -1) {
clearInterval(timex);
time = null;
alert("Time out!! :(");
}
}, 1000);
}
$("#stopbtn").click(function() {
clearTimeout(timex);
});
<script src="https://code.jquery.com/jquery-2.0.3.min.js" integrity="sha256-sTy1mJ4I/LAjFCCdEB4RAvPSmRCb3CU7YqodohyeOLo=" crossorigin="anonymous"></script>
<script type="text/javascript" src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/js/bootstrap.min.js"></script>
<input type="text" id="timer_this" value="1000">
<span id="timer"></span>
<button id="start">start</button>
<button id="stop">stop</button>
<button id="pause">pause</button>
<button id="reset">reset</button>
several little things to have a working sample :
var timex; should be declared globally if you want to set is value in the several callbacks
in the reset callback you do var timex = 0; first issue you recreate a local function variable timex but you to do it twice that is not valid
for the reset function you can simplyfy it by :
create a stop function
your reset callback became
$("#reset").click(function() {
stopTimer();
startTimer();
});
var sec = $("#timer_this").val();
var timex;
$("#start").click(function() {
var sec = $("#timer_this").val();
startTimer('start');
});
$("#reset").click(function() {
stopTimer();
startTimer();
});
$("#stop").click(stopTimer);
function stopTimer() {
$("#timer").html($("#timer_this").val());
clearTimeout(timex);
timex = undefined;
}
function startTimer() {
if (!timex) {
sec = $("#timer_this").val();
}
timex = setInterval(function() {
$("#timer").html(sec);
sec--;
if (sec == -1) {
clearInterval(timex);
time = null;
alert("Time out!! :(");
}
}, 1000);
}
$("#pause").click(function() {
clearTimeout(timex);
});
<script src="https://code.jquery.com/jquery-2.0.3.min.js" integrity="sha256-sTy1mJ4I/LAjFCCdEB4RAvPSmRCb3CU7YqodohyeOLo=" crossorigin="anonymous"></script>
<script type="text/javascript" src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/js/bootstrap.min.js"></script>
<input type="text" id="timer_this" value="1000">
<span id="timer"></span>
<button id="start">start</button>
<button id="stop">stop</button>
<button id="pause">pause</button>
<button id="reset">reset</button>
The timex variable was assigned in the scope of the startTimer function and is lost once that function returns, so it is not available when you later come to call clearTimeout on it.
When building out your logic, its often useful to create functions that describe the actions you want to happen, then call them from your UI components. This helps make the code more readable and reduces repetition.
For example, it's simpler to have clearTimeout in one place, and just call it from whichever methods need to stop the timer. It also helps later when getting the UI to reflect the current state of the application since there's only one way to get to that state.
Here's an example of this sort of approach:
let timerx, sec;
$("#start").click(function() {
// Toggle between start/stop
sec ? stopTimer() : startTimer();
});
$("#pause").click(function() {
// Toggle between pause/resume
timerx ? pauseTimer() : resumeTimer();
});
function startTimer() {
// Stop any existing timer
stopTimer();
// Grab the new count
sec = parseInt($("#timer_this").val());
// Start the timer
resumeTimer();
$("#start").text("stop");
$("#pause").prop("disabled", false);
}
function resumeTimer() {
// Start timer
timerx = setInterval(() => {
// Update time remaining
$("#timer").text(--sec);
if (sec === 0) {
// Handle timeout
stopTimer();
alert("Time out!! :(");
}
}, 1000);
$("#timer").text(sec);
$("#pause").text("pause");
}
function stopTimer() {
// Start timer and clear remainng time
sec = 0;
pauseTimer();
$("#timer").text("");
$("#start").text("start");
$("#pause").prop("disabled", true);
}
function pauseTimer() {
// Just stop the timer
timerx = clearInterval(timerx);
$("#pause").text("resume");
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.2.4/jquery.min.js"></script>
<input type="number" id="timer_this" value="1000">
<button id="start">start</button>
<button id="pause" disabled>pause</button>
<p id="timer"></p>

How setTimeout function is working in this case? [duplicate]

This question already has answers here:
Recursive setTimeout in javascript
(2 answers)
Closed 5 years ago.
<body>
<input type="text" value="10" id="txtBox" /><br/><br/>
<input type="button" value="Start Timer" onclick="startTimer('txtBox')" />
<input type="button" value="Stop Timer" onclick="stopTimer()" />
<script type="text/javascript">
var intervalId;
function startTimer(controlId)
{
var control = document.getElementById(controlId);
var seconds = control.value;
seconds = seconds - 1;
if (seconds == 0)
{
control.value = "Done";
return;
}
else
{
control.value = seconds;
}
intervalId = setTimeout(function () { startTimer('txtBox'); }, 1000);
}
function stopTimer()
{
clearTimeout(intervalId);
}
</script>
</body>
I am new to JavaScript. I was going through some tutorial, the above code snippet I came across, which works completely fine for starting a countdown timer from 10 to 0 in every 1000 millisecond interval. I am confused that how setTimeout() is calling the function repeatedly, when it is supposed to call the function only once after waiting 1000 millisecond.
function startTimer(){...} is a named function. One advantage of named function is that it call itself from inside its body. The code you shared is exploiting this concept & the code inside setTimeout is calling the same function startTimer
intervalId = setTimeout(function() {
startTimer('txtBox');
}, 1000);
The startTimer() function will be called by the setTimeout() function. Then when the startTimer() function is executing, it will call the setTimeout() function again. So it is a lot like a loop.
You can also use setInterval instead:
intervalId = setInterval(function(){
startTimer('txtbox');
}, 1000);
use it outside the startTimer function. It will call the startTimer function once every 1000 milliseconds repeatedly.

Show reset button after counter reaches zero

I would like to hide and then show the "Reset" button as soon as the counter reaches zero.
Index.html:
<html>
<head>
<script
src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js">
</script>
<script type="text/javascript" src="countdown.js"></script>
</head>
<body>
<input type="text" id="timer">
<script type="text/javascript">
timer = new Countdown();
timer.init();
</script>
<button id="reset">Reset</button>
<script type="text/javascript">
$("#reset").click(function(){
//timer = new Countdown();
timer.reset();
});
</script>
</body>
</html>
Please see http://jsfiddle.net/orokusaki/o4ak8wzs/1/ for countdown.js
AWolf's answer is a bit fancier than mine, and they made some good points about your code, but I tried to keep mine simple and tried not to change your original code too much.
Your init() function will now hide the Reset button, and I had the update_target() function show the Reset button when the timer expired.
Fiddle: http://jsfiddle.net/rgutierrez1014/o4ak8wzs/4/
In this jsFiddle you'll find the updated code and how you could add that behaviour.
I've also improved your code a bit. It's easier to write Countdown.prototype = { init: function() {...}, ...} then writing Countdown.prototype.init = function() {...}
I also changed your setInterval to setTimeout and start a new timeout every second. That's easier and you don't need to clear the interval at the end. Also the callback function for your interval seemed a bit strange and that probably won't work.
You could add your click handlers in the init method of your countdown object like this $('#start').click(this.start.bind(this)); the .bind(this) is used to change the context inside the click handler to the currently used object. Then this inside of the handler is your object and you can access everything with this.
To hide the reset button at start I've used the css display: none; and if you are at zero then show the button with $('#reset').fadeIn('slow'); or $('#reset').show(); if you don't want the animation.
Update 13.03.2015
As mentioned in the comments I've improved the code and now I'm using a jQuery Countdown plugin.
Please have a look at the latest version in this jsFiddle.
I think it's much better then the other code.
(function () {
function Countdown() {
this.start_time = "00:30";
this.target_id = "#timer";
//this.name = "timer";
}
Countdown.prototype = {
init: function () {
console.log('init called');
this.reset();
$('#start').click(this.start.bind(this));
$('#reset').click(this.reset.bind(this));
},
reset: function () {
time = this.start_time.split(":");
//this.minutes = parseInt(time[0]);
this.seconds = parseInt(time[1]);
this.update_target();
},
tick: function () {
if (this.seconds > 0) //|| this.minutes > 0)
{
if (this.seconds == 0) {
// this.minutes = this.minutes - 1;
this.seconds = 59
} else {
this.seconds = this.seconds - 1;
}
this.start();
}
else {
// show reset button
$('#reset').fadeIn('slow');
}
this.update_target();
},
start: function() {
console.log('start called');
//setTimeout(this.name + '.tick()', 1000);
setTimeout(this.tick.bind(this), 1000);
},
update_target: function () {
seconds = this.seconds;
if (seconds < 10) seconds = "" + seconds;
$(this.target_id).val(this.seconds);
}
};
var counter = new Countdown();
counter.init();
})();
#reset {
display: none;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input type="text" id="timer">
<button id="start">Start</button>
<button id="reset">Reset</button>

Javascript auto page refresh code

this is the code that comes in head section and it will automatically refresh the whole page in 1 min as i put 6000 in the code below
<script type="text/javascript">
setTimeout('window.location.href=window.location.href;', 6000);
</script>
is there any way for example, when there's 10 seconds left to refresh the page then, a button will display and say "Click here to reset timer" and it will reset that timer to 1 min again?
<script language="javascript">
var timeout,interval
var threshold = 15000;
var secondsleft=threshold;
startschedule();
window.onload = function()
{
startschedule();
}
function startChecking()
{
secondsleft-=1000;
if(secondsleft <= 10000)
{
document.getElementById("clickme").style.display="";
document.getElementById("timercounter").innerHTML = Math.abs((secondsleft/1000))+" secs";
}
}
function startschedule()
{
clearInterval(timeout);
clearInterval(interval);
timeout = setTimeout('window.location.href=window.location.href;', threshold);
secondsleft=threshold;
interval = setInterval(function()
{
startChecking();
},1000)
}
function resetTimer()
{
startschedule();
document.getElementById("clickme").style.display="none";
document.getElementById("timercounter").innerHTML="";
}
</script>
Please wait...<span id="timercounter"></span>
<button id="clickme" style="display:none;" onclick="javascript:resetTimer();">Click here to reset timer</button>
Assuming you have the following html for the button:
<button id="cancel-reload-button" style="display: none" onclick="cancelReload()">Cancel Reload</button>
And this as the script (Note: this gives the idea, but is not neccesarily fully tested):
// Variable for holding the reference to the current timeout
var myTimeout;
// Starts the reload, called when the page is loaded.
function startReload() {
myTimeout = setTimeout(function() {
document.getElementByID("cancel-reload-button").style.display = "inline";
myTimeout = setTimeout(function() {
window.location.reload();
} 10000)
}, 50000);
}
// Cancel the reload and start it over. Called when the button is
// clicked.
function cancelReload() {
clearTimeout(myTimeout)
startReload()
}
// On page load call this function top begin.
startReload();
I created two functions, one for starting the reload and the second one for cancelling it.
Then I assigned the timeout to the variable myTimeout which can be used to later cancel the timeout.
Then I called myTimeout twice - Once for 50 secs, at which point it shows the button and once for 10 secs after which it finally reloads.
How about below? If you click on OK to reset timer, it would keep giving the confirm box every 50 seconds. If you click cancel, it will refresh the page in 10 seconds.
setInterval(function(){ var r = confirm("Reset Timer");
if (r == true) {
setTimeout('window.location.href=window.location.href;', 60000);
} else {
setTimeout('window.location.href=window.location.href;', 10000);
}
}, 50000);
Note: In your question you specified 1 minute, but your code works for 6 seconds(6000 -- > 6 seconds not 60 seconds) I have included for a minute
You can use 2 setTimeout calls, one to make the "Reset" button show up and another one for the refresh timer reset. The trick is to store the second setTimeout on a global variable and use clearTimeout to reset it if the button is pressed.
Here is some JavaScript code to illustrate:
<script type="text/javascript">
var autoRefreshTime = 30 * 1000; // 60000ms = 60secs = 1 min
var warningTime = autoRefreshTime - (10 * 1000); // 10 secs before autoRefreshTime
waitTimeout = setTimeout('window.location.href=window.location.href;', autoRefreshTime);
warningTimeout = setTimeout('ShowResetButton();', warningTime);
function ShowResetButton() {
// Code to make the "Reset" button show up
}
// Make this function your button's onClick handler
function ResetAutoRefreshTimer() {
clearTimeout(waitTimeout);
waitTimeout = setTimeout('window.location.href=window.location.href;', autoRefreshTime);
}
</script>
The way I would do it is make a function with a timeout, and invoke that function
<script type="text/javascript">
var refreshFunc = function(){
setTimeout(function(){
var r = confirm("Do you want to reset the timer?");
if(r === false){
window.location.href=window.location.href;
}else{
refreshFunc();
}
}, 6000);
};
refreshFunc();
</script>
One big problem with using confirm in this case is you cannot program it to reject. You would have to implement you own modal/dialog box so you can auto reject in 10 seconds.
Try using setInterval():
var time;
$(function() {
time = $('#time');
$('#reset').on('click', reset);
start();
});
var timer, left;
var start = function() {
left = +(time.text()); //parsing
timer = setInterval(function() {
if (0 <= left) {
time.text(left--);
} else {
clearInterval(timer);
location.replace(location);
}
}, 1000);
};
var reset = function() {
if (timer) {
clearInterval(timer);
}
time.text('59');
start();
};
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<h1><span id='time'>59</span> second(s) left</h1>
<input id='reset' value='Reset' type='button' />

invoke function everytime a boolean becomes false in JavaScript

I'm trying to invoke a function everytime the "paused" property of a html audio element gets false.
I have a timer which shall count the time a audiofile is actually listened to (i also want to exclude the time while searching with the time bar).
I tried it with SetInterval checking all the time for the status of "paused". Unfortunately this isn't working accurately and quite often misses the status change and so lets the time counter count on.
Is there a simple way to invoke a function everytime a boolean changes?
Help would be very appreciated.
Thanks, f.
Thanks for you answer. Unfortunately this didn't do the trick.
Here's the Code:
<html>
<head>
</head>
<body>
<h5 id="test">Audio Timer</h5>
<audio id="player" src="kerry.wav" controls></audio>
<form name="d">
<input type="text" size="8" name="d2">
<h1 id="time"></h1>
</form>
<script>
var audio = document.getElementById("player");
var millisec = 0;
var seconds = 0;
var timer;
function display() {
if (millisec >= 99) {
millisec = 0
seconds += 1
} else
millisec += 1
document.d.d2.value = seconds + "." + millisec;
timer = setTimeout("display()", 10);
}
function starttimer() {
if (timer > 0) {
return;
}
display();
}
function stoptimer() {
clearTimeout(timer);
timer = 0;
}
function startstoptimer() {
if (timer > 0) {
clearTimeout(timer);
timer = 0;
} else {
display();
}
}
function resettimer() {
stoptimer();
millisec = 0;
seconds = 0;
}
setInterval(function () {
var time = audio.paused;
if (time == false) {
startstoptimer();
}
}, 1);
</script>
</body>
</html>
Unfortunately the SetInterval(function().. isn't fast enough to track the audio.paused. which seems is what i need. As you can see this code always does start the timer, but quite often it doesn't stop it when you press pause or when you use the time bar to seek through the audio.
Any idea how to accomplish that?
Create a variable that calls your audio tag
var yourAudio = document.getElementById("audio")
And then
yourAudio.onpause=YourFunction()
If that is not what you are looking for, post your code or part of it, give us more information.
With a while (true) my page didn't even load. But I finally brought it to life by adding two event listeners listening to "playing" and "pause" which invoke the startstoptimer function.
audio.addEventListener("playing", startstoptimer);
audio.addEventListener("pause", startstoptimer);
those two lines were all it needed :)
thanks.

Categories

Resources