Javascript stopwatch incrementing by powers of two - javascript

I have the following code for my simple stopwatch, which only counts the number of seconds with no formatting whatsoever:
function countDown(from, interval, callback) {
interval = interval || 1000;
var current = 0;
var onCount = function() {
current++;
if (current <= from) {
callback(current, from);
setInterval(onCount, interval);
}
}
onCount();
}
This is called with an onclick, with the following code:
countDown(600, 1000, function(current, from) {
time_out.innerHTML = current;
});
Putting in a console.log(current), I can see two problems. First, though it does go through every number, it seems to get faster and faster, by powers of two. In the output div, the first tick will be 1, the second will be 2, the third will be 4, the fourth will be 8, and so on. Furthermore, it does not actually stop counting when it hits 600, even though it stops updating the div. What did I do wrong here?

You use setInterval which will call the callback at a set interval every time the function is called, resulting many many calls to countDown()
Maybe you wanted to use the setTimeout function instead, which will only call the function once after the delay.

Related

delay between function in loop jquery

I have a jQuery function that shows modal boxes:
function ShowAnonce(){
...
jQuery(".ShowAnonce").show();
jQuery(".ShowAnonce").animate({opacity: 1},300).delay(1800).animate({opacity: 0},300);
}
And what I want to do is to show this box 10 times with different random intervals. I used a for loop and setTimeout like this:
for(i=0;i<10;i++){
setTimeout(ShowAnonce(),Math.random()*100);
}
but it shows the box 10 times with no delay. What can I do to fix it?
Also, why can't I do the following at the end of ShowAnonce function?
jQuery(".ShowAnonce").hide();
If I do it, it doesn't shows me box because style display:none keeps being assigned.
Math.random() can return value in decimals also like , 0.123. Which the setTimeout() cannot take . Try Math.ceil (Math.random()) this will give you an integer but might give the same value again and again .
I would try (Math.ceil (Math.random()) *10 ).
As an alternative you can use setInterval as below instead of for loop for x number of times:
var x = 0;
var intervalID = setInterval(function () {
ShowAnnounce();
if (++x === 10) {
window.clearInterval(intervalID);
}
}, Math.random()*100);
Another post about each() iteration gave me an answer. So it works for me:
var time = 0;
for(i=0;i<10;i++){
time = time + Math.random() *10000;
setTimeout(ShowAnonce, time);
}

Recursive function to print numbers in JavaScript

I'm trying to make a recursive function to print 1 to 10 in JavaScript, my current code is:
function rec10(x)
{
if (x < 10)
{
$('#text').val(x+1);
x = x+1;
rec10(x);
}
}
The problem is, everytime I activate this function, the text box only shows "10" directly, i want the code to move from 0 to 1, to 2... until 10. Showing each one of them in the text box.
I tried to use setInterval and setTimeout but I didn't figure it out how to work with that. Thank you very much
instead of:
rec10(x);
call
setTimeout(function() { rec10(x); }, 1000);
With setInterval you can using code below:
function rec10(x) {
var interval = setInterval(function() {
if (x >= 10) clearInterval(interval);
$('#text').val(x++);
}, 1000);
}
JavaScript is single threaded, which means while your code runs, the changes you make to the DOM won't be seen on the browser until your code finish.
You need to give control to the browser for couple of seconds, it can be done with setTimeout:
function rec10(x){
if (x < 10){
$('#text').val(++x);
setTimeout(function(){
rec10(x);
},20);
}
}
Did you resort to setInterval/setTimeout only because you can't make a working recursive function?
If that's the case, how about this recursive function below without using setInterval/setTimeout:
function rec10(x) {
if (x <= 10) {
if (x <= 0) x = 1;
//append?
$('#text').val(x);
rec10(x + 1);
}
}
rec10(1);
But the problem with the code above is it will happen so fast you won't notice the printing of numbers 1 up to 9.
If you want to see the those numbers then I suggest you just append the value to your placeholder $('#text').
But if you really wanna see the numbers being printed and then being replaced by the next number, then you can refer to the answers posted by other users which uses setInterval/setTimeout.

How to add multiples of a number and overwrite previous entry using js timing?

I am trying to create a function that continuously adds the same number to itself. Or simply displays multiples of one number every so many seconds with the setInterval method.
For now, let's just say I want to display multiples of ten.
I know how to get a regular while loop to simply display multiples of ten in a row, but what I want to do here is continually replace the previous text every time the function is called. I am trying to create a game and this is going to be the experience calculator. So it needs to display the total experience earned over the given time.
I was trying something along the lines of this:
window.setInterval(
function writeExp ()
{
var j;
while (rounded > 0)
{
var i = w*10;
var j = j + i;
}
document.getElementByID("exp").innerHTML=j;
}, experience)
This seems logical enough to me, but obviously something is wrong, as it does not work. I have tried googling various things like how to sum numbers in javascript or continuously sum, among others, but it is somewhat difficult to word to get it more centered to my needs. So this is the best way to get my questions answered.
There are lot of undefineds in your code, but general example would be
var interval = 1000,
result = 0,
elem = document.getElementByID("exp");
window.setInterval(function () {
result *= 10;
elem.innerHTML = result;
}, interval);
or without global variables
var interval = 1000,
multiply = function (elem) {
var result = 0;
return function () {
result *= 10;
elem.innerHTML = result;
}
};
window.setInterval(multiply(document.getElementByID("exp")), interval);

For Loop with dynamic numbers in timeout

I have a for loop that is running a timeout function that needs dynamic numbers but instead I'm getting the end result instead of the increments in some cases.
Here's my code (p.s. yes I realize setting 'start' variable inside for loop is not ideal):
var new_answer_start = 0;
var seconds = 0;
for (start=0; start<50; start++) {
new_answer_start = new_answer_start + 50;
seconds = seconds + 10000; //10 seconds
setTimeout(function(){reloadXMLDoc(xmlurl, new_answer_start);},seconds);
}
What I'm trying to accomplish is that increasing every 10 seconds the function will run with the new_answer_start equaling increments of 50. Instead I'm getting every 10 seconds the function is outputting each time starting at 2500 (the last set of numbers after 50 loops). I've had a similar issue before, something to do with closures and I used "let" to fix it then. However when I tried:
let new_answer_start = new_answer_start + 50;
I started getting NaN (not a number) errors. I thought it was weird that the timeout would increment in seconds (10, 20, 30, etc) but not the variable sent to the function. I'm assuming that's because once the function goes to run 10 seconds later, the variable increment has completed to the end. So how do I send the 'fixed' number to the function?
After doing research on similar questions here, I also tried putting the number into a closure:
setTimeout(function(){reloadXMLDoc(xmlurl, (new_answer_start));},seconds);
But this still start outputting at 2500.
Try using an actual closure:
setTimeout((function (new_answer_start) {
return function () {
reloadXMLDoc(xmlurl, new_answer_start);
};
})(new_answer_start), seconds);
window.new_answer_start = 0;
var interval = setInterval(function() {
window.new_answer_start = window.new_answer_start + 50;
}, 10000);

Is there a way to make this slideshow move automatically?

This is the slideshow that we used:
http://www.littlewebthings.com/projects/blinds/
and this is the JS file:
http://www.littlewebthings.com/projects/blinds/js/jquery.blinds-0.9.js
However, this slideshow doesn't have a setting that makes it go through each image automatically. You still have to click on the numbers below it to see the images. Does anybody know what to add into the javascript code to make it go through each image automatically?
Thanks!
This solution uses closures and recursion.
var SlideChanger = function(seconds_each) {
var index = -1;
// on the first cycle, index will be set to zero below
var maxindex = ($(".change_link").length) - 1;
// how many total slides are there (count the slide buttons)
var timer = function() {
// this is the function returned by SlideChanger
var logic = function() {
// this is an inner function which uses the
// enclosed values (index and maxindex) to cycle through the slides
if (index == maxindex)
index = 0; // reset to first slide
else
index++; // goto next slide, set index to zero on first cycle
$('.slideshow').blinds_change(index); // this is what changes the slide
setTimeout(logic, 1000 * seconds_each);
// schedule ourself to run in the future
}
logic(); // get the ball rolling
}
return timer; // give caller the function
}
SlideChanger(5)(); // get the function at five seconds per slide and run it
What we are doing here is exposing the inner function timer outside of the function in which it was defined (SlideChanger). This function (timer) has access to the variables defined inside of SlideChanger (index and maxindex).
Now that we have set up the variables in the enclosing environment and a function to return to the caller, we can set up the logical engine in logic. When logic is run, it uses index and maxindex to determine which slide should be shown next, shows the slide, and schedules itself to be run again in the future.
When called, the returning function calls logic to get the ball rolling. Then logic repeats indefinitely by scheduling itself to run in the future each time it is run.
So, to summarize, we call SlideChanger with a numeric argument x. It returns a function that, after being called, will change the slide every x seconds.
Another way to write the same concept.
(function(seconds_each) {
var index = -1;
// on the first cycle, index will be set to zero below
var maxindex = ($(".change_link").length) - 1;
// how many total slides are there (count the slide buttons)
return function() {
// this is the function returned by SlideChanger
var logic = function() {
// this is an inner function which uses the
// enclosed values (index and maxindex) to cycle through the slides
if (index == maxindex)
index = 0; // reset to first slide
else
index++; // goto next slide, set index to zero on first cycle
$('.slideshow').blinds_change(index); // this is what changes the slide
setTimeout(logic, 1000 * seconds_each);
// schedule ourself to run in the future
}
logic(); // get the ball rolling
}
})(5)(); // get the function at five seconds per slide and run it
JavaScript is a nice language with many functional programming constructs such as higher order functions (functions that either create functions or accept functions as parameters) and anonymous functions. For more info see http://www.ibm.com/developerworks/web/library/wa-javascript.html
ecounysis's solution would work but it's unnecessarily complicated. Here's a simpler way using setInterval, modulo, and not wrapping it in an extra function:
function startSlideshow(ms) {
var index = -1;
var count = $(".change_link").length - 1;
return setInterval(function() {
index = (index + 1) % count;
$('.slideshow').blinds_change(index);
}, ms);
}
After a quick scan through the source, I didn't see a built-in API for auto-advancing the slides. However, you could use an alternative slideshow, like this one:
http://jquery.malsup.com/cycle/
All you need is to include a timer on it and call the blinds_change event. That works for me.

Categories

Resources