Timers in JavaScript | KIRUPA

By default, your code runs synchronously. That is a fancy of way of saying that when a statement needs to execute, it executes immediately. There are no and, ifs, or buts about it. The concept of delaying execution or deferring work to later isn't a part of JavaScript's default behavior. That doesn't mean the ability to delay work to a later time doesn't exist! If you swerve just slightly off the main road, there are three functions that allow you to mostly do just that (and more) - setTimeout, setInterval, and requestAnimationFrame.


This is a companion discussion topic for the original entry at http://www.kirupa.com/html5/timers_js.htm

Hi again Kirupa,

Your explanation of JS timer functions are as usual very clear. One thing that stands out is the idea that the JS engine is single threaded. You can’t set a timer to keep something waiting while you run a couple of processes that might need to generate values to inject into the waiting function.

As an example, if I want to use an “onclick” on an image tag to pass a number through to a variable, then also use an addEventListener to identify the click mouse position, then use that result to trigger an image swap plus animation of the changed image to a new position from the point you clicked on.

Could you perhaps do a piece on getting things to happen in the desired order? What you can’t do and how to get round it etc?

That would be exceptionally useful. Thanks!

That would be an interesting article. The challenge (and opportunity :P) is the single-threaded part you mentioned. Unless you are using async/promises/etc., the order you want to do something in JavaScript is consistent. Since you want that consistency, you get that for free. Let’s say that you have code that looks as follows:

foo();
bar();

for (var i = 0; i < 1000; i++) {
    console.log("doing something");
}

blah();

All of those statements will execute in order. If any of those function calls end up blocking the page, that function call will be the last thing your code hits. The rest of the code will not run either. The order is maintained.

For the scenario you outlined, where are you seeing things happening out of order?

Ok. Typical of me it’s a little complicated. So let me describe it in a little more detail.

Firstly, I am preloading the thumbnail images for my “table” into an Array to force them into the cache as your tut says. No problem. Because I want to easily add more images by simply putting them into the folder, correctly labelled, I am using your “detect if an image exists” routing to iterate through the number sequenced filenames until it can’t find one. That routine sets the number of images I want to add. I then iterate through a loop to charge up my Array. So far I have that part working fine.

The next part of the page load procedure is that I will use document.write to add the code for the correct number of items in my “table” (I will decide whether I want to use an actual table or divs later).

An addEventListener is set up to wait for a click in the defined area which is the total size of the “table” based on a surrounding div. That will fetch the mouse click coords using your excellent routine (slightly edited).

Each thumbnail image is armed with an “onclick” event handler which passes a number to a stored variable to identify which image needs to be displayed.

The large images themselves get inserted inside one of two container divs. They both start off styled to be tiny and invisible and are initially located at the top left corner of the “table” area.

When you click an image, the first container should move to where the mouse clicked (eventListener routine), the swapImage function then runs to change the img.src to the clicked image (using the “onclick” variable) and then triggers the style change to make the container transition to large size and new position with opacity 1.

When you click another image, the same process injects the new image into container 2, while the first image is restyled and should return to the point where it “emerged” from previously.

Finally, when the visitor clicks a main menu item to hide the gallery panel (which slides away), the current large image should zoom and shrink back to its start point as it fades away.

I am having trouble getting the things to happen in the correct sequence. I think part of my problem might be to do with the addEventlistener click detection and the “onclick” click detection. Whichever routine begins first will hog the thread until its finished as far as I can tell, then the other one will fire. Either I must know which one fires first so I can adjust my code accordingly, or I must find another way to accomplish the same result using only one click event.

For the broader view of how this image gallery will be used the website is www.smooth-operator.co.uk

My experimental build is still at www.smooth-operator.co.uk/anim_builder.html

Btw - the whole thing is designed to be responsive to window size changes as well…I will be designing a separate site for smaller mobile devices I think.

I will be continuing to fiddle with it during the day and will tell you any updates I might have.

Kind regards.

Okay - so fiddling with this and going through it slowly in my head over and over, I am now thinking that perhaps the issue is not one of when which event fires. Maybe the problem is when I am assigning the new style to each container. More fiddling…

Brain is frying. Lol! Need to give it a bit of a break! There must be faults in my logic as to how I am moving through the process…

Currently (and this might change soon) the shrinking image is going to where I just clicked while the growing image is coming from where the previous click was!!! The wrong way round!! Its like Rubiks Cube!! Lol!!