That is, naively, I had code like this:
fadeIn functions are something like so: (taken from the previously linked SO answer, credits to Ibu)
The basic idea was to fade out the image element, and then change it’s source to point to the next image, and then fade it back in. Sounds easy right? Yes, except that nothing waits for the timer inside fadeOut to finish. Rather the fade in function is executed and messes up the transition with flickering images as both functions try to reduce and increase the opacity of the new image. We think that those functions will be asynchronous and nicely wait for the previous timer to finish.
Those two functions work perfectly if they are triggered by other events separately, but when used back to back like I did, it’ll flicker and not do what we intended it to do.
Short Answer: Callbacks
I figured I should write this post as many articles and posts regarding image fade in and out do not highlight the need for a callback or to nest the function inside, this is because they are usually considered as having separate events/buttons to trigger them, and not as a transition.
A quick and dirty fix would be to nest the fade in function inside the fade out function and call that once the timer has been cleared, like so:
This works, but isn’t very maintainable, what if you wanted to have another function for a transition, or not just change the image, but the dimensions as well? You’d have to either duplicate functions (violating the Don’t Repeat Yourself (DRY) principle) or manually change the references or have some kind of if-else conditional.
The better way to do it is via callbacks. Since functions are also a first class citizen, you can actually pass in a function as a parameter. And then call the function when you want to. This would let you execute whatever function you want called after the previous function has completed. This makes it general and very flexible.
After which you can use the function like so!
What the above does is basically after the completion of the fade out transition (where the timer is cleared), the anonymous function is called which first changes the image source and then calls the fadeIn function. Flexible, reusable and not specifically hard-coded!
If you’re going to pass in a non-anonymous function as a callback, make sure you do not add the parentheses, as that will immediately invoke the function, and then take that return value (which might be undefined) as the call back. Here’s an example.
What you shouldn’t do.
Lastly, if you used JQuery (which the whole point of this was to not use it), the
delay() function would work as we would normally expect, as the callback logic has been abstracted out for us. Here’s a blog post that shows how to execute functions once an animation is finished.