Jump to content

problem with the setInterval() function.


atar.yosef

Recommended Posts

Hi there! I've built the following code snippet in order to animate a div element by using the setInterval() function to change the div element's height and width at a specified rate. the problem is that according to the arguments I've provided to the function, I've expected it to last 2 seconds. but unfortunately, actually the function executed during approximately 8 seconds and I don't understand why. please help me figure it out what is going here.

<html><head><title></title><script type="text/javascript">try{function start(){var divFirst = document.getElementById("divFirst");var divControl = document.getElementById("divControl");function expand(eID, exHeight, exWidth, timing){i = 0;t = setInterval(innerExpand, timing);function innerExpand(){i++;eID.style.height = exHeight++;eID.style.width = exWidth ++;s = new Date();s = s.getSeconds();divControl.innerHTML = i + "---" + s;if(i == 1000){clearInterval(t);}//end if.}//end innerExpand().}//end expand().divFirst.onclick = function(){expand(divFirst, 20, 100, 2);}}//end start().}//end try statement.catch(err){alert("there's an error in this page. \n the error message is:\n" + err.message + "\n the error name is: \n" + err.name + "\n and the error details are:\n" + err.constructor + "\n and the error stack is: \n" + err.stack);}//end catch statement.</script><style type="text/CSS">div#divFirst {background-color:red;}div#divControl {position:absolute; top:10px; left:200px;}</style></head><body onload="start()"><div id="divFirst">my first div!!</div><div id="divControl"></div></body></html>

Any help will be appreciated! Thanks in advance! atar.

  • Like 1
Link to comment
Share on other sites

Javascript timing isn't precise. You're telling it to run that function once every 2 milliseconds, and to stop after you've ran it 1000 times. That doesn't necessarily mean it's going to take 2 seconds. If it takes longer than 2ms to execute that code (update the height, render the div, update the width, render the div, create a Date object, etc) then it's going to get backed up. It sounds like it takes more like 8ms to run that code.

  • Like 1
Link to comment
Share on other sites

@justsomeguy:Thank you very much about your detailed answer!! So isn't there an alternative way to achieve my goal? (i.e. to create a function that will expand an element size up to the specified size and will last during the specified time).Thanks in advance!!Atar.

Link to comment
Share on other sites

Animation can't be adjusted perfectly, but to start off, 2 milliseconds is really short, that means a framerate of 500 frames per second. Try a shorter framerate, for example 40 frames per second which is 25 milliseconds.Each time a function is called using setInterval, there's an error margin, the less times you call it the less the errors can add up.

  • Like 1
Link to comment
Share on other sites

@Ingolme: Thanks you on your reply!! I just wanted to know what's your meaning in your last sentence:

Each time a function is called using setInterval, there's an error margin, the less times you call it the less the errors can add up.
Why does the setInterval() function cause an error, and what's exactly error margin? Thanks in advance! atar.
Link to comment
Share on other sites

An error margin isn't a computer error, it's just a probabilty that a value is different than expected and how far off from the expected value it will be. If you want setInterval() to make a function run every 1000 milliseconds and there's an error margin of 10 milliseconds then you can expect any amount of time between 1000 and 1010 to pass. Normally error margins are also negative (980 to 1010) but the computer's minimum amount of time will always be the amount of time you gave it.

  • Like 1
Link to comment
Share on other sites

If you want to see that for yourself, create a clock or timer in Javascript that uses setInterval to call a function every second to update the counter. Make a note of when you start it and come back later to check on it. If you give it enough time then you'll find out that eventually it will be several seconds or minutes off. It doesn't kick off exactly every 1000 milliseconds. Javascript in a web browser was not intended for precision timekeeping, especially when you're doing things that cause the browser to re-render all or part of the page. Here's an example screenshot from one of my tests. I created a stopwatch widget and wanted to test if it was accurate, so I filled the screen with them and let them run overnight. Some of them were several minutes off, so obviously they weren't working right. I had to rewrite the code for the widget to use another algorithm to make sure that it would stay accurate. IMAG0024 (640x383).jpg

  • Like 1
Link to comment
Share on other sites

@ingolme and justsomeguy:Thanks you very much about your detailed and well explained answers!! I really appreciate it!!Just two more things I want to know:1) if JavaScript fails to manage timing functions accurately, which other programming languages can be used to perform accurate timing functions? (Either those programming languages are web based like php and asp or they aren't web based like JAVA and C++).2) Ingolme has said that:

I had to rewrite the code for the widget to use another algorithm to make sure that it would stay accurate.
and I'm very curious and interested to know which algorithm he used in order to achieve more accurately results. I'll be glad if he'll share his algorithm with me.Thanks in advance!!Atar.
Link to comment
Share on other sites

No, you're quoting the wrong person, I didn't do that. However, for a precise timer, I use Javascript's Date() object. Every language will have timing problems if you ask it to do too much between one function call and the next. Besides that, basically any language has OK timing.

Link to comment
Share on other sites

Since I was building a stopwatch that had a pause button, I set it up so that it recorded the time when it started. Every second it got the current time, subtracted from the start time to get the difference, and displayed that in the timer. If you hit pause and start it again then when you hit pause it would save the current total time. When you start it again it sets a new start time but adds the previous total when it calculates the time to display. That means that it doesn't necessarily update every second, and sometimes when it updates it would jump by 2 seconds depending on timing, but it was always displaying the correct elapsed time since you started it.

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...