Skip to page content or skip to Accesskey List.
Search evolt.org
evolt.org login: or register

Work

Main Page Content

Using setInterval() to Make a JavaScript Listener

Rated 3.53 (Ratings: 9) (Add your rating)

Log in to add a comment
(17 comments so far)

Want more?

 
Picture of pixelmech

Tom Dell'Aringa

Member info | Full bio

User since: May 20, 2002

Last login: July 10, 2007

Articles written: 1

Oftentimes when you are building something, you need some kind of function to "listen" for either an event or a condition. You need this to happen continously so you can act upon it when it does happen.

Quite often programmers attempt to use setTimeout() in these cases, which isn't what you want. What you need is the red-headed stepchild (apologies to redheads) of setTimeout(), setInterval().

Often if you mention setInterval() to somebody, they reply one of two ways:
  1. You mean setTimeout()? or
  2. Huh?

I'm not sure why this is - maybe too many "cut and paste" scripts out there with setTimeout() in them. Anyway, there is a vast gulf of difference between the two, and the gulf is very simple to understand.

  • setTimeout() allows you to DELAY the execution of an expression or evaluate a function.
  • setInterval() allows you to EVALUATE an expression or a function at set INTERVALS (thus the name - neat eh?).

So, who cares about setTimeout(), we've all heard enough about that. Let's have a bash at an example.

The Need

Your mission, should you accept it: you have two text input boxes. When text is entered into both fields, you want to display a hidden div. You can't do this on the submission of the form, because the hidden div contains more input that has to be sent along with it. (Play along, it's just an example!)

What you need to know is when both fields have entries. (We won't worry about error checking, etc.) This is where our buddy setInterval() comes in.

Our Page Code:

<html>
<body>
<form id="form">
<input type="text" id="text1">
<input type="text" id="text2">
<div id="hidden" style="display: none;"><input type="text" id="text3"></div>
<input type="submit" value="submit">
</form>
</body>
</html>

First, Our Function

First, we need a function to do what we want to happen when our condition is met. What it needs to do is display our hidden block:

function showHiddenDiv()
{
	var textBox1 = document.getElementById("text1").value;
	var textBox2 = document.getElementById("text2").value;
	var ourDiv = document.getElementById("hidden").style;
	
	if(textBox1 != "" && textBox2 != "")
	{
		ourDiv.display = "block";
return true;
	}
	return false;
}

We set up some local variables to point to our two text boxes and their values (what's in them) and our hidden div's style. Then we have our condition here - if both text boxes are not equal to empty (they must both be full) we change the display style to block, and it becomes part of the page flow.

If one of the text boxes is still empty, the 'else' condition fires and we return 'false.' You don't have to do this, but I understand its good technique to return some value from your functions, and apparently the strict warnings in some new browsers (if you have the feature turned on) will send you a warning if you don't.

Second, the Interval

Now, we need to set up our interval to periodically fire off our function to do the checking or "listening." The structure for the setInterval() method is:

var interval_name = setInterval([expression_or_function], [time_period]);

And if you use a function, it must be quoted and include the brackets. Now, you don't want to go nuts and check the thing every 10 milliseconds - consider that a Bad Thing(tm) and a performance hit. However, once per second would be fine, and once that second entry is made your hidden div should be showing.

Our Interval Method:

var ourInterval = setInterval(&quot;showHiddenDiv()&quot;, 1000);

That's it - that's all. Once the page is loaded, showHiddenDiv() will run every second until it's first condition is met, and the hidden div is shown. Great! But then what? How do you stop it? The beauty is, since you set your interval to a variable, that variable is now the id for your interval. All you need is to add the clearInterval() method to your function, with the variable name as its parameter. So your final function looks like this:

function showHiddenDiv()
{
	var textBox1 = document.getElementById("text1").value;
	var textBox2 = document.getElementById("text2").value;
	var ourDiv = document.getElementById("hidden").style;
	
	if(textBox1 != "" && textBox2 != "")
	{
		ourDiv.display = "block";
		clearInterval(ourInterval);
	}
	else
	{
		return false;
	}
}

Other Issues

Of course in this case, you might have to deal with issues such as, what if the user erased one input and so forth. But that's your job. If the user reloads the page, you're golden, because your script reloads too and your interval restarts.

So tap into the power of setInterval() and "listen" to your heart's content!

Tom got his start in web development in the winter of 1995 when his boss threw an HTML book in his direction stating "we should learn about this world wide web thing." Since then he has worked at dot.com era startups with no real business model, web integrator Scient and lately as a freelance and contracting developer. Experienced in HTML, JavaScript, and CSS as well as server-side scripting languages, he has worked on everything from simple brochure sites to enterprise level portals.

It was during one of these large projects that he finally got fed up with the "IE only" mentality of coding. Additionally, even large corporations seemed unaware of the benefits of separating style from content and still produced bloated, non-standard code. In response to this, and a corresponding discussion on Evolt's thelist, he founded MACCAWS.org in late 2002. MACCAWS is a group of developers seeking to help other developers make the commercial case for using web standards to their clients and bosses. This means showing them that beyond the programmatical and practical benefits, there is also a fiscal benefit as well.

Lately part of his role on teams involves explaining to developers what LABEL tags are, that they shouldn't build layouts with tables nested ten levels deep, showing them alternatives to using 127 spacer gifs per page, proving the benefits of a global stylesheet and defining DOCTYPEs and how to use them.

He realized the dot.com era was over when his paychecks started bouncing right after the big welcome party he had been flown to in San Francisco. He currently resides in the Midwest with his wife and two children. He plays guitar and and even recorded a demo CD with his band. Constantly scouring Ebay and garage sales for Charlie Brown and Snoopy paperbacks, he is finding it very hard to find the Peanuts Parade versions...anyone?

Always the better option

Submitted by codepo8 on October 9, 2002 - 04:03.

I discovered that function some time ago, and implemented into a slideshow script (example) and it behaves a lot better than setTimeout.

login or register to post comments

Why people use setTimeout()

Submitted by Martin Tsachev on October 9, 2002 - 10:38.

setTimeout() is a more supported function than setInterval and it can do the same work (although sometimes it takes a few more lines of code).

With JavaScript you should use what's widely supported not a fancy new function.

login or register to post comments

Fancy!?

Submitted by pixelmech on October 9, 2002 - 11:30.

Hey Shaggy,

I'll respectfully disagree :) how is setTimeout() "more supported"? They are both part of the JavaScript Specification. setInterval() is compatible with version 4 browsers and above. This *hardly* makes it a "fancy new function."

If you are writing code for legacy browsers, say version 3 and below, then you can't use it. My article was written for those of us who are coding for modern browsers in today's world, who want to use the best tools available. Both functions are fully supported. And setInternval() is the quicker *and* better way to do what I am proposing.

Also, I'm not sure how you would do the same work with setTimeout(). Let's see the code. Its going to be messy and not very efficient.

This isn't to say setTimeout() doesn't have a place, because it does. But lets use the right tool for the job!

Tom

login or register to post comments

setTimeout()

Submitted by liorean on October 9, 2002 - 13:03.

I would advice against using setTimeout() in any situation because it in iewin 4-6 versions and in nn<5 has memory leaks. I do not know whether Mozilla also have those leaks, but iewin is enough for me to avoid it. Mozilla on the other hand has other problems with setTimeout, such as that it locks until an even happens and vice versa depending on what was initiated first.

Oh, and setInterval has good enough support unless you want to support third generation browsers.

login or register to post comments

setTimeout()

Submitted by Martin Tsachev on October 11, 2002 - 05:17.

My article was written for those of us who are coding for modern browsers in today's world, who want to use the best tools available...

Also, I'm not sure how you would do the same work with setTimeout(). Let's see the code. Its going to be messy and not very efficient.

Pixelmech, with JavaScirpt you can't always code just for the "modern browsers". Anyway before setInterval even existed people had ways to do the same with setTimeout, besides the code needed is not so complicated as it seems to you.

Liorean, I haven't noticed any memory leaks with the setTimeout function but then most of the time I'm using Unix boxes and if using WIndows it's NT based.

login or register to post comments

Memory leaks

Submitted by liorean on October 11, 2002 - 07:28.

The memory leaks exists in NT based environments as well, and in fact in the now defunct Unix version too.

login or register to post comments

Coding for Modern Browsers

Submitted by pixelmech on October 11, 2002 - 08:51.

Shaggy,

As I stated setInterval is only going to have problems with version 3 browsers. I have not worked on a project that codes for such legacy browsers in over 2 years, so my article is timely in my opinion.

If you are in an environment where you have to code for legacy browsers, my solution isn't for you, its that simple.

You haven't offered any good criticism of the article, all you have said is "setTimeout is better to do that with" even though the two functions are vastly different (as explained in the article). Its almost as if you didn't read the article other than the first part of it. Do you have some criticism of the actual code? Do you have a setTimeout function to show that is better? or that does the same thing?

I'm all for criticism, believe me. But let's make it constructive, and let's have it make sense, instead of calling part of core javascript a "fancy new function" when it has been around for years.

login or register to post comments

setTimeout demo

Submitted by Martin Tsachev on October 11, 2002 - 11:26.

Lioren, sorry I haven't used IE for Unix and I wouldn't.

Pixelmech, I have a working demo using setTimeout() in a place where you could use setInterval() - this is How to create a DHTML slideshow with fading effects and also an example (the explanation is also available on Evolt somewhere). Look at the JavaScript source of the example because it's updated after the article was published.

login or register to post comments

What about events?

Submitted by mad_hatter on October 12, 2002 - 05:04.

No offense, but I would say that this article goes down the wrong path entirely. Yes, there is an argument of setInterval vs. setTimeout and each one has its use. The whole "legacy" argument doesn't hold much weight, considering NS2.0 isn't really on the radar. The memory leaks are a legitimite point, but not much of an issue in small applications.

My issue with this article is that it argues for the use of setInterval when built in event listeners provide a much cleaner, faster, powerful and logical solution. Why set some interval when you can just catch the onChange or onKeyUp events in the form fields? Instead of saying how setInterval is a better solution than setTimeout, it should make a case of when setInterval is better than built in events (or a way to effectively "fake" events, which could get very in depth). Otherwise, it is really a waste.

login or register to post comments

Event Listeners

Submitted by pixelmech on October 12, 2002 - 09:26.

I agree that event listeners are a very valid solution. They might be better, I'm not sure. I think that event listeners are a step up in complexity from my solution, and I have not played with them yet.

I wanted to share this because it worked for me in a production environment. It was a small amount of code, it got the job done and the client was happy. I'm not saying there are not other ways. For someone like me who isn't yet familiar with event listeners, this worked great and was a fast solution

I also think, from what *little* I know of event listeners, that my solution would be quicker and easier. Not necessarily better, but easier.

Actually, if you are well versed on event listeners - I for one would like to see an article on it :)

login or register to post comments

Re: Event Listeners

Submitted by Jeff Howden on October 12, 2002 - 17:23.

Event listeners and event handlers are the same thing. In the case of this article, calling a function from the onchange event handler of both form input's would have done the job without unneeded cpu usage to execute the watching function over and over again and would have caused the result from the function to be instantaneous rather than as much as 1000 milliseconds after the condition in the function was satisfied.

Here's how I would have done it using event handlers. I've purposely altered the original block of HTML because &lt;input&gt; tags must have a name attribute in order to send data to the server. So, I've changed the id attribute to name to satisfy this requirement.

<html>
<body>
<form>
<input type="text" name="text1">

Here's the toggleHidden() function you'll need for this:

<script language="JavaScript" type="text/javascript">
<!--
  function toggleHidden(oElement1, oElement2, oHidden)
  {
    if(document.getElementById)
      document.getElementById(oHidden).style.display = (oElement1.value && oElement2.value) ? 'block' : 'none';
  }
//-->
</script>

Notice I was careful to test for support of the getElementById() method before using it. Not doing so would result in all sorts of nasty, unnecessary errors for browsers that don't support that method.

Here's the working sample:

As you can see the hidden &lt;div&gt; shows up when the cursor leaves either field and both fields have values. If you want an instantaneous response swap out the use of the onchange event handler for an onkeydown, onkeyup, or onkeydown event handler like the example below which uses the onkeyup event handler.

.jeff

login or register to post comments

Good example, my poor test case...

Submitted by pixelmech on October 12, 2002 - 22:22.

Jeffs way I have to say is better, in this case. Let me back up a bit and say that I picked a poor example for my test code. I was trying to be simple about it and kind of ruined it.

In the case where I actually used it, heres how I used it:

  • I began by loading a page. It was part of a frameset and had lots of dynamic stuff going on.
  • Lots of things were happening in this page, and some of it depended on data from other sources, in other frames.
  • In particular, I had to wait to call a certain object until a dyanmic tree with all its data from a DB be loaded - this was in another frame, and data came from various places.
  • So I needed something to trigger the tree being "ready" - I used the setInterval()
So in a nutshell, a JS engine that does things with objects loads on the main page - it can't do certain things though, until the tree was fully loaded. I had a function to check this, and only allow the engine to do its thing when the tree was loaded.

For various reasons, I couldn't use the onLoad event handler for that frame, it didn't work. I can't post the code since its protected by NDA (bummer) so thats the best explanation I can give. Next time I will be more careful about my example and simplifying it too much. Suffice it to say I couldn't use an event listener in that case, and setInterval() fit the bill!

Tom

login or register to post comments

Wait for other frame to load

Submitted by SidX on July 14, 2003 - 15:59.

There is a javascript function to check if other frame has been fully loaded, I ve used it before, I just can't remember what it is. I would avoid using setInterval for any even listener ... I would only use it to do sequencial process like for example animation.

login or register to post comments

possible hack-workaround for any needed listener?

Submitted by whan on June 24, 2004 - 21:10.

haven't tried this yet:
create form element

position it offscreen someplace, at the end of the content (to minimize interaction with it)

set display to none or vis to hidden (whatever works)

attach an onchange handler to the element

dump your changing content (presumably an array or object or something) into this form element

use its onchange handler to register changes and fire events (instead of setinterval)
hmmm, does this work? ........ I'm trying to setup a javascript to actionscript event queue and maybe this will make another platform possible (IE Mac has significant remaining users and significant memleaks...perhaps this would make proting to that platform doable)

login or register to post comments

setTimeout(), setInterval()

Submitted by srisri on November 22, 2005 - 01:32.

This is a good article and good arguments..... I was having a problem with my application. I need to reload the page of my application after a set of Interval. Finally I used both the functions and achieved what i want.
function loadWindow() {
setTimeout('setInterval(\'history.go(0)\',100000)',10000);
}
onLoad i am calling the loadWindow() function.
But i want to take the expert comments whether there is any better way to write this.

login or register to post comments

setInterval question

Submitted by thoughtdimension on May 26, 2006 - 18:19.

Hi, I've created an AJAX application and I've implemented setInterval() to run a repeating process. I know that an id is returned to allow you to stop the timer by calling clearInterval(id). But what I want to know is how can I determine if the timer is running? Can I somehow query the timer id? What I really want to know is how long has passed since the last interval, and what time remains until the next call. Let me illustrate: idReceipt = setInterval("Process();", myDynamicVariable); clearInterval() is called when a user presses a button, or if the process fails, so I need to know if the timer is running and how much time is remaining. Is this possible? I would much appreciate it if you could help me with this question.

login or register to post comments

use a CTimer object

Submitted by bluenick on October 2, 2006 - 01:24.

Hi You can achive your pourpuse by using a "user defined object" wich you can design like the Timer object (in vb, ...) or with 3 arrays and an "ad hoc" defined function for the timer events:

use an array for setInterval ids, one for your variable intervals, one for eval strings, and one to sum the intervals (obtaining the elapsed time for each "object").

Indeed I use a CTimer object wich I designed like the above Timer object and all I have to do is to override the onTimer function before calling the start method.

Unfortunatelly this site thinks that my code is souspicios so I can't post it.

Bye DMD

login or register to post comments

The access keys for this page are: ALT (Control on a Mac) plus:

evolt.orgEvolt.org is an all-volunteer resource for web developers made up of a discussion list, a browser archive, and member-submitted articles. This article is the property of its author, please do not redistribute or use elsewhere without checking with the author.