I've recently run into a rather nasty bug, wherein the code was loading a <select>
dynamically via JavaScript. This dynamically loaded <select>
had a pre-selected value. In IE6, we already had code to fix the selected <option>
, because sometimes the <select>
's selectedIndex
value would be out of sync with the selected <option>
's index
attribute, as below:
field.selectedIndex = element.index;
However, this code wasn't working. Even though the field's selectedIndex
was being set correctly, the wrong index would end up being selected. However, if I stuck an alert()
statement in at the right time, the correct option would be selected. Thinking this might be some sort of timing issue, I tried something random that I'd seen in code before:
var wrapFn = (function() { var myField = field; var myElement = element; return function() { myField.selectedIndex = myElement.index; } })(); setTimeout(wrapFn, 0);
And this worked!
I've got a solution for my problem, but I'm uneasy that I don't know exactly why this fixes my problem. Does anyone have an official explanation? What browser issue am I avoiding by calling my function "later" using setTimeout()
?
The main advantage to using setImmediate() over setTimeout() is setImmediate() will always be executed before any timers if scheduled within an I/O cycle, independently of how many timers are present.
clearTimeout() is a function which helps in clearing out the previously set time out time which was set by making use of the setTimeout() function which creates an ID value and this value, in turn, helps in clearing the time out which is sent as a parameter to JavaScript clearTimeout().
Most of the time, we use “setTimeout()” to let some code run a certain period of time. However, it can cause problems when it is not used not carefully.
What is setTimeout() in Node. js? The setTimeout function is used to call a function after the specified number of milliseconds. The delay of the called function begins after the remaining statements in the script have finished executing.
In the question, there existed a race condition between:
Your code was consistently winning this race and attempting to set drop-down selection before the browser was ready, meaning that the bug would appear.
This race existed because JavaScript has a single thread of execution that is shared with page rendering. In effect, running JavaScript blocks the updating of the DOM.
Your workaround was:
setTimeout(callback, 0)
Invoking setTimeout
with a callback, and zero as the second argument will schedule the callback to be run asynchronously, after the shortest possible delay - which will be around 10ms when the tab has focus and the JavaScript thread of execution is not busy.
The OP's solution, therefore was to delay by about 10ms, the setting of the selected index. This gave the browser an opportunity to initialize the DOM, fixing the bug.
Every version of Internet Explorer exhibited quirky behaviors and this kind of workaround was necessary at times. Alternatively it might have been a genuine bug in the OP's codebase.
See Philip Roberts talk "What the heck is the event loop?" for more thorough explanation.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With