Js Timeout Display - javascript

I am not sure if this possible using my current method, but I am wondering if it is possible to show the timeout as a counter on page.
I am creating a page to show data entering the database in 15 second intervals however the timeout can be changed.
var counter = 15 * 1000
var autoRefresh = function(){
clearInterval(interval);
interval = setInterval(autoRefresh, counter);
$.pjax.reload({container:"#content",async:false, timeout: 2000});
return false;
}
var interval = setInterval(autoRefresh, counter);
Ideally I need to show a countdown timer till the next refresh. Is it possible or is there an alternate route I can take to achieve this?

The only real way is to run your interval every second, display the countdown and, if 15 seconds have past, do what you want to do.
var counter = 15 * 1000;
var currentCycle = 0;
var autoRefresh = function(){
currentCycle++;
if (currentCycle >= (counter/1000)) {
currentCycle = 0;
$.pjax.reload({container:"#content",async:false, timeout: 2000});
} else {
console.log((counter/1000-currentCycle)+' seconds remaining');
}
return false;
}
var interval = setInterval(autoRefresh, 1000);

Related

Smoothly increase interval time with JS

How can i play a sound at an interval (for example once every second) and gradually decrease the time between the intervals?
At the moment, i use two intervals with setInterval, the first one plays the sound each second, the second setInterval speeds up the first interval every 20 seconds. This works, but it leaves a nasty "pause" between the intervals.
Is there a better way?
Example code (just to clarify, not necessary to read):
var audio = new Audio('track.wav');
var baseSpeed = 1000;
var myInt;
var changeInt;
//Starts a Run
function beatInterval() {
audio.play();
};
//Speeds up the other interval
function speedUpInterval() {
baseSpeed = baseSpeed - 20
clearInterval(myInt);
myInt = setInterval(beatInterval, baseSpeed);
console.log(baseSpeed);
myInt = setInterval(beatInterval, baseSpeed);
changeInt = setInterval(speedUpInterval, 20000);
You can delay adjustment of speed, until interval function is actually executed:
var speedChanged = false;
function beatInterval() {
if(speedChanged) {
speedChanged = false;
clearInterval(myInt);
myInt = setInterval(beatInterval, baseSpeed);
}
audio.play();
};
function speedUpInterval() {
baseSpeed = baseSpeed - 20
speedChanged = true;
console.log(baseSpeed);
}

Timer does not actually stop after pause button is clicked

Timer is displayed as if it is kind of stop after pause button is clicked, but when i click resume i find out that counter continue to countdown behind the scene. I guess there are issues with setInterval. Please help me. My project on CodePen for reference if you need.
My timer function
function timer(seconds) {
clearInterval(countdown);
const now = Date.now();
const then = now + seconds * 1000;
displayTimerLeft(seconds);
console.log({
now,
then
});
countdown = setInterval(() => {
if (!isPaused) {
const remainSeconds = Math.round((then - Date.now()) / 1000);
if (remainSeconds < 0) {
clearInterval(countdown);
return;
}
displayTimerLeft(remainSeconds);
}
}, 1000);
}
Pause and start click events
pause.addEventListener('click', function() {
isPaused = true;
return;
})
start.addEventListener('click', function() {
isPaused = false;
})
Looking at your code, I suppose the problem is you keep the same then value, which is ultimately a timestamp at which the timer should end. Right now, instead of pausing the countdown, you stop the display from changing.
I would advise using your variable seconds instead (and calculating display using modulo %), and decreasing it every second. That way, pausing the display would effectively pause the decreasing.
Keep a reference of the current time and manually add a second at each tick.
function timer(seconds) {
clearInterval(countdown);
const t = new Date();
const end = t.getTime() + seconds * 1000;
displayTimerLeft(seconds);
console.log({
t,
end
});
countdown = setInterval(() => {
if (!isPaused) {
const remainSeconds = Math.round((end - t.getTime()) / 1000);
if (remainSeconds < 0) {
clearInterval(countdown);
return;
}
displayTimerLeft(remainSeconds);
t.setSeconds(t.getSeconds() + 1);
}
}, 1000);
}
Demo: http://codepen.io/miguelmota/pen/wgMzXY
setInterval returns a unique id that can be used to stop the timer using clearInterval:
var id = setInterval(function(){
console.log('running every 300 ms');
},300);
clearInterval(id) // stop timer

setInterval for stopwatch

I'm trying to make a stopwatch. Here's the code:
var min = 0, sec = 0, censec = 0
$("#startBtn").on("click", function() { // when start button is clicked
$(this).hide(); // start is hidden
$("#stopBtn").show(); // stop is shown
setInterval(add, 10); // the censec will be increased every 10 millisecond.
$("#censec").text(censec);
})
function add() {
censec++;
if (censec == 100) {
censec = 0;
sec++;
if (sec == 60) {
sec = 0;
min++;
}
}
}
The problem is that setInterval() happens only at once. The censec only changes from 00 to 1. That's it.
P.S. I'm new to coding, so if there are other mistakes, please don't hesitate to tell me.
The setInterval calls to add will definitely repeat. But your code is only ever showing the value of censec once, when you start the timer.
If you want to update the display every hundredth of a second, put the code showing the value in add.
Separately, the code as it is in the question won't run at all, because it has a ReferenceError on the first line. Those ; should be ,.
Example (this also stores the timer's handle and clears the timer when you click the stop button):
var min = 0, sec = 0, censec = 0;
// Note ---^--------^
function add() {
censec++;
if (censec == 100) {
censec = 0;
sec++;
if (sec == 60) {
sec = 0;
min++;
}
}
$("#censec").text(censec);
}
var timer = 0;
$("#startBtn").on("click", function() { //when start button is clicked
$(this).hide(); //start is hidden
$("#stopBtn").show(); //stop is shown
timer = setInterval(add,10); //the censec will be increased every 10 millisecond.
});
$("#stopBtn").on("click", function() {
clearInterval(timer);
timer = 0;
$(this).hide();
$("#startBtn").show();
});
<input type="button" id="startBtn" value="Start">
<input type="button" id="stopBtn" value="Stop" style="display: none">
<div id="censec"></div>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
Note that although it may be mostly fine to use setInterval for displaying, using it to track the elapsed time is a bad idea; it frequently doesn't fire precisely.
Instead, record when you started
var start = Date.now();
...and then when the timer fires, figure out how long it's been since you started
var elapsed = Date.now() - start;
Then use the value (milliseconds) in elapsed to figure out your display.
Your variable declarations have ; instead of , .
Also checking numbers on equality should be done by using === but that is not the problem here.
Your also not updating the view in your timer. So updating of your html should also be in your function that is called by the timer.
If the goal is to use real seconds and milliseconds, I also suggest using the Date type because your timer will be late and not real-time. So still use the timer with the interval you like but in the add function you call the date object. You can replace the 3 vars for one datetime of type Date which will give you the granularity that you like.
var dateTimeStart = null, censecElement = null, timer = null;
$("#startBtn").on("click", function() {//when start button is clicked
$(this).hide(); // start is hidden
$("#stopBtn").show(); // stop is shown
if(timer === null) {
// timer was not started
dateTimeStart = new Date();
timer = setInterval(updateCensec, 10); //the censec will be increased every 10 millisecond.
console.log("Started timer");
}
});
$("#stopBtn").on("click", function() {//when stop button is clicked
$(this).hide(); // stop is hidden
$("#startBtn").show(); // start is shown
if(timer) {
// timer is started/running
clearInterval(timer);
console.log("Stopped timer");
}
timer = null;
});
function updateCensec() {
var sensec = 0, sec = 0, dateTimeNow = new Date(), diffMilliseconds = 0;
diffMilliseconds = dateTimeNow - dateTimeStart;
censec = parseInt((diffMilliseconds % 600 ) / 10); // convert milliseconds to centi seconds
sec = parseInt(diffMilliseconds / 600);
if(censecElement === null) {
censecElement = $("#censec");
}
censecElement.text(sec + ":" + censec);
}
I would like to suggest that you do not update your view every 10 milliseconds even if you want your stopwatch to show time in centiseconds.

Displaying one JS countdown after another

I'm trying to display a second countdown after the first one finishes. I'm using meteor. This is the timer:
sec = 5
#timer = setInterval((->
$('#timer').text sec--
if sec == -1
$('#timer').fadeOut 'fast'
sec=
timer
return
), 1000)
This is how I call it
When the template is rendered I call a setTimeout and a countdown displays
Template.selector.rendered = ->
window.setTimeout(startGame, 5000)
timer
When game starts I need a second countdown. I managed it like this:
sec = 5
sw = 0
#timer = setInterval((->
$('#timer').text sec--
if sec == -1
if sw == 0
sw = 1
sec = 20
else if sw == 1
clearInterval timer
return
), 1000)
But there has to be a better way.
If you plan to use many timers, you could make an object to achieve that. Here is an example taken from here You could adapt it to your case using custom events:
ReactiveTimer = (function () {
// Constructor
function ReactiveTimer(interval) {
this._dependency = new Tracker.Dependency;
this._intervalId = null;
if(_.isFinite(interval))
this.start(interval);
};
ReactiveTimer.prototype.start = function(interval){
var _this = this;
this._intervalId = Meteor.setInterval(function(){
// rerun every "interval"
_this._dependency.changed();
}, 1000 * interval);
};
ReactiveTimer.prototype.stop = function(){
Meteor.clearInterval(this._intervalId);
this._intervalId = null;
};
ReactiveTimer.prototype.tick = function(){
this._dependency.depend();
};
return ReactiveTimer;
})();

How to run a javascript function X seconds?

I am using setInterval to run a Javascript function that generates a new, random integer in a div. the timer starts when I click on the div. I am having problems with stopping it form generating new numbers after five seconds.
Using setTimeout, I hide the div after 5 seconds; that stops random numbers, but I lose the div.
How can I efficiently stop the generating of numbers in the div, and not hide it?
HTML:
<div id="div" onmousedown='F();'>Click here</div>
JS:
function F(){
var div = document.getElementById("div");
setInterval(function(){
var number = Math.floor(Math.random()*28) ;
div.innerHTML = number;
}, 1000);
setTimeout(function(){
div.style.display = 'none';
},5000);
};
Just use a counter to keep track of the number of times the interval has ticked and then use clearInterval to stop it:
var count = 0;
var intervalID = setInterval(function() {
// generate your random number
count++;
if (count === 5) {
clearInterval(intervalID);
}
}, 1000);
Something hastily written, but what you want to do is keep track of your interval handle and then clear it. You can do this with a setTimeout
var forXsecs = function(period, func) {
var handle = setInterval(func, 1000);
setTimeout(function() { clearInterval(handle); }, period * 1000);
}
The timing is not perfect. Matt's answer would also work.
Another option is a slight change on Matt's answer that removes setInterval and just uses timeouts.
var count = 0;
var forXsecs = function(period, func) {
if(count < period) {
func();
count++;
setTimeout(function() {forXsecs(period, func);}, 1000);
} else {
count = 0; //need to reset the count for possible future calls
}
}
If you just want to simply let it run once each second and that 5 times you can do it like this:
HTML:
<div id="5seconds"></div>
JS:
var count= 0;
setInterval(function(){
if(count < 5){
document.getElementById('5seconds').innerHTML = Math.random();
count++
}
},1000);
This will generate a random number each second. until 5 seconds have passed
you should use clearInterval to stop the timer.
To do so, you pass in the id(or handle) of a timer returned from the setInterval function (which creates it).
I recommend clearing the interval timer (using clearInterval) from within the function being executed.
var elm = document.querySelector("div.container");
var cnt = 0;
var timerID;
function generateNumber()
{
cnt += 1;
elm.innerText = cnt;
if (cnt >= 5) {
window.clearInterval(timerID);
}
}
timerID = window.setInterval(generateNumber, 1000);
.container {display:block; min-width:5em;line-height:5em;min-height:5em;background-color:whitesmoke;border:0.1em outset whitesmoke;}
<label>1s Interval over 5s</label>
<div class="container"></div>

Categories