I'm trying to refresh a div from Javascript at each loop and see 1, 2, 3, ....
The following code works, but only displays the final result (9998).
How is it possible to display all the steps?
Thank you in advance.
<html>
<head>
</head>
<body>
<div id="cadre" style="width=100%;height=100%;">
<input type="button" value="Executer" onclick="launch();"/>
<div id="result" ></div>
</div>
<script type="text/javascript">
function launch(){
for (inc=0;inc<9999;inc++){
document.getElementById('result').innerHTML = inc;
}
}
</script>
</body>
</html>
JavaScript execution and page rendering are done in the same execution thread, which means that while your code is executing the browser will not be redrawing the page. (Though even if it was redrawing the page with each iteration of the for loop it would all be so fast that you wouldn't really have time to see the individual numbers.)
What you want to do instead is use the setTimeout() or setInterval() functions (both methods of the window object). The first allows you to specify a function that will be executed once after a set number of milliseconds; the second allows you to specify a function that will be executed repeatedly at the interval specified. Using these, there will be "spaces" in between your code execution in which the browser will get a chance to redraw the page.
So, try this:
function launch() {
var inc = 0,
max = 9999;
delay = 100; // 100 milliseconds
function timeoutLoop() {
document.getElementById('result').innerHTML = inc;
if (++inc < max)
setTimeout(timeoutLoop, delay);
}
setTimeout(timeoutLoop, delay);
}
Notice that the function timeoutLoop() kind of calls itself via setTimeout() - this is a very common technique.
Both setTimeout() and setInterval() return an ID that is essentially a reference to the timer that has been set which you can use with clearTimeout() and clearInterval() to cancel any queued execution that hasn't happened yet, so another way to implement your function is as follows:
function launch() {
var inc = 0,
max = 9999;
delay = 100; // 100 milliseconds
var iID = setInterval(function() {
document.getElementById('result').innerHTML = inc;
if (++inc >= max)
clearInterval(iID);
},
delay);
}
Obviously you can vary the delay as required. And note that in both cases the inc variable needs to be defined outside the function being executed by the timer, but thanks to the magic of closures we can define that within launch(): we don't need global variables.
var i = 0;
function launch(){
var timer = window.setInterval(function(){
if( i == 9999 ){
window.clearInterval( timer );
}
document.getElementById('result').innerHTML = i++;
}, 100);
}
launch();
Try
document.getElementById('result').innerHTML += inc;
Related
I was trying to repeatedly call a function using setInterval. When I call a function without arguments, it works. However, on calling a function with arguments, the function is called only once.
Here is the js fiddle
HTML
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<script src="./check.js">
</script>
</body>
</html>
check.js Without arguments - works
setInterval(myfun,100)
var mycounter = 0;
function myfun()
{
console.log(mycounter++)
}
check.js With arguments - does not work
setInterval(myfun(0),1000)
function myfun(mycounter)
{
console.log(mycounter++)
}
When you add the parentheses the function is called right away, and the returned result is used in the interval, which in your case is the default return value of undefined.
What you're really doing is
var result = myfun(0); // returns undefined
setInterval(result, 1000); // no go, result is undefined
function myfun(mycounter) {
}
if you want to pass arguments, the easiest is to just use an anonymous function
setInterval(function() {
myfun(0);
}, 1000);
Modern browser (not IE9 and below) now support passing arguments directly in setInterval
setInterval(myfun, 1000, 0); // "0" is passed as the first argument to myfun()
of course, incrementing the variable can only be done if the variable exists in a scope outside the callback function for the interval
right...
what setInterval wants is a function that it can call,
in the first case you are providing the function
in the second case you are calling the function and then returning its value
to accomplish what you are trying to do in the second case you would do this:
setInterval(function() {myFun(20)}, 1000}
which creates a NEW function that wraps your call to myFun inside it... comprehend?
Now the other thing to keep in mind is that setInterval keeps calling the function forever until you stop it.... so you could do this:
var counter = 20;
setInterval(function() {counter = counter-1; if (counter > 0) myFun()}, 1000)
which will call myFun every second until counter expires...
But this is still not perfect a the interval will keep running forever so what you want is something like this (its a working example, click the run button at the bottom)
function nTimes(fn, count, time) {
var interval = setInterval(function() {
if (count > 0) {
count = count - 1;
fn(count);
} else {
clearInterval(interval);
}
}, time)
};
function myFun(x) {
$('#output').html($('#output').html() + x + '</br>')
}
nTimes(myFun, 20, 1000)
<div id='output'></div>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
Working Fiddle: https://jsfiddle.net/0tesf2rk/
var counter = {
value: 0,
increase: function () {
console.log(counter.value);
counter.value++;
}
};
counter.value = 20;
setInterval(counter.increase, 1000);
I am trying to make a function(next) that takes a function and a wait time as its arguments. It will then have a counter that will be increased by the function calls.
var up = function() {
var counter = 0;
return counter += 1;
};
var next = function(fn, wait) {
var total = 0; //set total variable to 0
var x = fn(); //call the function and set answer to a variable
total+=x; //add the answer to the total
var n = setTimeout(function(){fn();}, wait);
//THIS BIT DOES NOT GIVE ME 1? Instead I get any number from 16 (depenging on how many times I call it! It increases as I keep calling the function....?!)
total += n;
return total;
};
next(up,1000);
I am totally confused as to why setTimeout is working like this?!
I have looked around for an answer for this and have not hit lucky- I am sorry if I have missed the question on here if it has been asked before!
I did come across this question and tried putting the variable counter outside, however this did not seem to make any difference...
This question seems even closer to the area I am confused about however I am not any closer to comprehending my problem any help would be greatly appreciated as to why the return values that I am getting are so much higher than what I expect them to be..
Another approach that I tried was this:
var next = function(func, wait) {
var storedAnswer = 0;
var answer = function() {
return storedAnswer;
}
var increase = func;
setTimeout(increase, wait);
return answer();
};
next(up, 100); // gives me 0...? the up function here is defined in the above code...
But this ended up with me not getting any movement in the answer...
setTimeout returns the timeout id, not the return value of the callback.
var timeoutID = window.setTimeout(code, [delay]);
Try this:
setTimeout(function(){total += fn();}, wait);
The value that setTimeout returns is an int. But it is also a global counter of timeouts. Which is to say that every timeout shares the same counter. So that you get 16 just means that somewhere, in some part of your page, 15 other timeouts had already executed.
This is perfectly normal to get back an integer of 16 or basically of not 1 in that scenario, and using that integer with a clearTimeout for example will still properly reference the timeout used.
Aside
In node.js (which doesn't seem like what you are using), the mechanism is the same, except that a timeoutObject is returned instead which may still be used to clear the timeout. It is also used for continuations and other server-side related timing mechanisms.
n is the return value of setTimeout, which is a numeric identifier that you can pass to clearTimeout in order to cancel the timeout.
Your basic problem here is that setTimeout simply registers a function to be called after the given delay, and then execution immediately continues to the next line. So this line:
total += n;
is not waiting until your timeout completes. It's happening immediately, and n is, like I said, not the value you want.
You need your next function to take a callback that it can call when the timeout has completed.
var next = function(fn, wait, callback) {
var total = 0;
var x = fn();
total+=x;
setTimeout(function() {
var n = fn();
total += n;
callback(total);
}, wait);
};
You would call it like:
next(up, 100, function(total) {
// This function runs after the operation is done; do something with the total.
});
I have a function in JavaScript. I use setInterval in order to control my function. I also have another logic for controlling my function. I have a counter which is increased once one condition happens and is decreased when another condition happens. Now, sometimes the second condition does not happen and hence my function won't be resume anymore. (I pause my function when my first condition happen). Therefore, I want to wait at most 30 seconds for the second condition. If it does not happen, then I want to resume my function anyway. I have following code, but it does not work as I expect it. What happens is that it resume my function every 30 seconds. Then, it may be resumed while it should wait. Can someone let me know what is the problem with my code?
Please note that, the value for the counter may increase to more than 20. I mean the first and second condition may occur more than once.
function main()
{
// body
}
function increaseCounter()
{
counter += 1;
clearInterval(controller);
controlSecond = setInterval(function(){
counterSeconds += 1;
if (counterSeconds == 30)
{
counterSeconds = 0;
controller = setInterval(main, 100);
clearInterval(controlSecond);
}
}, 1000);
}
function decreaseCounter()
{
counter -= 1;
if (counter == 0)
{
counterSeconds = 0;
clearInterval(controlSecond);
controller = setInterval(main, 100);
}
}
Consider what happens if you call increaseCounter twice in a row.
On the first execution it will create interval A and assign it to controlSecond.
On the second execution it will create interval B and assign it to controlSecond, while interval A continues to fire off indefinitely. You won't stop it with clearInterval(controlSecond) because controlSecond no longer references interval A.
The problem is that you continue to set controlSecond and controller to a new interval without clearing them first. That results in the intervals being leaked with no way of clearing them. It's sort of like a memory leak where you have dynamically allocated memory but nothing pointed at it, but instead of renegade memory you have renegade intervals.
One way to prevent this is to make sure you always clear your interval before setting it.
I would also recommend that you implement controlSecond with a setTimeout because that is designed for tasks which only happen once.
Why not
var counter = 0
var timeout = null
function main () {
clearTimeout(timeout);
timeout = null;
}
function increaseCounter () {
counter++;
if (!timeout)
timeout = setTimeout(main, 30*1000);
}
function decreaseCounter() {
counter--;
if (counter === 0)
main();
}
I have a function that should postpone the call for the next function :
function waitFunc( func, time )
{
var startTime = performance.now();
var currTime = performance.now();
while ( (currTime - startTime) <= (time / 1))
{
currTime = performance.now();
}
func();
}
Another two function that i have are supposed to change the content of the tag i have in the body:
function showPlus()
{
//display plus
pictureImg.src = plus;
//blank only the form that contains input
inputForm.style.display="none";
pictureImg.style.display="block";
//after timeout start "showPicture" function
waitFunc(showPicture, 250);
//setTimeout(showPicture, 250);
}
function showPicture()
{
//generate picture pass
imgName = "../images/Slide"+ i + ".PNG";
if (i < 100)
{
//increase variable i by 1
++i;
//blank only the form that contains input
inputForm.style.display="none";
pictureImg.style.display="block";
//display picture
pictureImg.src = imgName;
//after timeout start "showForm" function
waitFunc(showForm, 750);
//setTimeout(showForm, 750);
}
}
In the html:
<img src="../images/Blank.png" id="pictures" name="pictures"/>
Currently i am trying to call to waitFunc function from showPlus function and i expect that showPicture function would be called after the timeout. PROBLEM: When i use waitFunc function the content does not change as it suppose. However, when i use setTimeout function everything works just great.
Can some please assist me (i hope that this is not a stupid question)?
P.S. you can find the page here.
Thank you!
EDIT: You can also find a jsfiddle here. Notice that the fiddle is using setTimeout so you can see how it is supposed to work; if you comment the setTimeout and uncomment the waitFunc line next to it, then you will be able to see the issue.
There's a function called setTimeout() which does exactly the same functionality you need. Why don't you use it instead of building JavaScript all over again.
Also, performance.now(); isn't supported in all the browsers:
https://developer.mozilla.org/en-US/docs/Web/API/Performance.now
Also, your function shouldn't work at all:
var startTime = performance.now();
var currTime = performance.now();
Here you should have startTime == currTime because you're setting the same value in less than 1 millisecond.
while((currTime - startTime) <= (time / 1))
Here, (currTime - startTime) should be equal to zero, and (time / 1) is equal to time.
I don't understand what you're trying to do, but if you're looking to "pass a function as a parameter", your question is a duplicate: Pass a JavaScript function as parameter
You must know that javascript is excuted in a single thread. If you run a wait function implemented using a while statement the main thread of the page will be frozen.
The difference of you waitFunc implementation and the setTimeout of javascript is that the setTimeout function run in a separated thread. By other side your function is executed synchronous. By example the showPicture function will take 75000 ms on it run because the loop will wait on each waiFunc 750 ms.
I hope that this help.
This code works perfect. When the page load the main thread is busy for 3 seconds set the 3.jpg image and after 2 seconds the image return to be the first image again. This is using you function and the settimeout.
<!DOCTYPE html>
<html>
<head>
<title></title>
<script src="js/lib/jquery-2.1.1.js"></script>
<script>
function waitFunc( func, time )
{
var startTime = performance.now();
var currTime = performance.now();
while ( (currTime - startTime) <= (time / 1))
{
currTime = performance.now();
}
func();
}
$(function(){
waitFunc(function(){
$('#dd').prop('src', '3.jpg');
}, 3000);
setTimeout(function(){
$('#dd').prop('src', 'A_Girl_In_The_Horizon_by_yeg0.jpg');
}, 2000)
});
</script>
</head>
<body>
<img id='dd' src="A_Girl_In_The_Horizon_by_yeg0.jpg">
</body>
</html>
I ran some tests and, as I mentioned in the question comment, the issue seems to be that the waitFunc that you use freezes the browser before it is able to load the picture and change the display.
I got something kind of working, but again, you may not like it: the solution would consist on using setTimeout (with a low milliseconds value: 1-20) to call waitFunc (with the value that you want minus the 1-20 milliseconds). Something like this:
setTimeout(waitAuxForm, 1);
And then you have the function:
function waitAuxForm() { waitFunc(showForm, 749); }
I have put it in a jsfiddle and you can see it working here.
This solution presents some issues too:
You have to rely on setTimeout for a low amount of time (you may not like this).
You may need more than 1-20 milliseconds to load the pictures (you may want to preload them and once cached, it would work even with a value of 1).
I hope it helps :)
Okay, so I was able to get this to work with the information you provided. Right out of the gates, looking at what you have, nothing is defined. However, assuming that you have inputForm and pictureImg defined correctly in both of the last functions, the only thing you're missing is to define i.
function showPicture()
{
var i = 0;
//generate picture pass
imgName = "../images/Slide"+ i + ".PNG";
[...]
}
I couldn't find anything wrong with your waitFunc function. If you substitute in a simpler function, it works as intended.
function waitFunc( func, time )
{
[...]
while ( (currTime - startTime) <= (time / 1))
{
currTime = performance.now();
console.log(time); // log so you can see, for testing
}
func();
}
waitFunc(function(){console.log("Hello, world!");}, 750); // wait 750 ms, then say "Hello, world!"
I'm trying to create fade in and fade out function with JavaScript, but it's not working. Please tell me what I'm doing wrong.I'm not getting transitioning effect.
var fade_in_btn = document.getElementById('fade-in'),
fade_out_btn = document.getElementById('fade-out'),
fading_div = document.getElementById('fading-div');
function sleep(milliseconds) {
var start = new Date().getTime();
for (var i = 0; i < 1e7; i++) {
if ((new Date().getTime() - start) > milliseconds){
break;
}
}
}
fade_out_btn.onclick = function(){
for (var i=100; i >= 0; i--) {
sleep(0010);
opacity_function(i);
}
}
fade_in_btn.onclick = function(){
for (var i=1; i <= 100; i++) {
sleep(0010);
opacity_function(i);
}
}
function opacity_function(opacity_value){
fading_div.style.opacity = opacity_value / 100;
fading_div.style.filter = 'alpha(opacity=' + opacity_value + ')';
console.log(fading_div.style.opacity);
}
Fiddle with HTML.
All code Working Fine. But from my point of view problem is the for...loop is not updating the value of opacity after each iteration; it's only updating the final value.
Please Help me to resolve this problem.
this is a pure JS answer that doesn't use requestAnimationFrame but i have chosen to discard your sleep function since it is an odd choice and bad practice (and yours doesn't work. also note that there can be no true sleep in JS.)
this works:
fade_out_btn.onclick = function(){
var i = 100;
var myint = setInterval(function(){
opacity_function(i);
i--;
if (i<0) clearInterval(myint);
console.log(i);
},10); //this is the number of ms between iterations of the codeblock in my setInterval function
}
[EDIT: some people were recommending setTimeout. I see no need for that, but in case you really want to use setTimeout, this is how I would do it:
var i = 100;
function fadeout(){
var myint = setTimeout(function(){
opacity_function(i);
i--;
if (i>0) fadeout();
},10);
}
fade_out_btn.onclick = fadeout;
notice two things:
1 - I pulled the definition of i outside of the function. you would have to be grabbing that value that you want to decrement from outside the function anyways, because your starting value for a fadeout would presumably not always be 100 but would be set to the current value of the opacity, i.e. the value of fading_div.style.opacity * 100.
2 - i bound a callback to the onclick.
regarding choosing between setInterval and setTimeout:
setInterval and setTimeout both simply schedule the execution of code. setInterval schedules events every x ms from when it is executed whereas a series of chained setTimeouts schedules an event in x ms, then executes again, then schedules another event in x ms. so there is a little bit of time overhead for setTimeout because the real time interval is x + (the time is takes to execute the codeblock once). it is possible have issues with using setInterval if the time it takes to execute once is larger than the specified interval but that would not affect such a simple program as yours. see here]