Every browser that supports XHTML (Firefox, Opera, Safari, IE9) supports self-closing syntax on every element.
<div/>
, <script/>
, <br></br>
all should work just fine. If they don't, then you have HTML with inappropriately added XHTML DOCTYPE.
DOCTYPE does not change how document is interpreted. Only MIME type does.
W3C decision about ignoring DOCTYPE:
The HTML WG has discussed this issue: the intention was to allow old
(HTML-only) browsers to accept XHTML 1.0 documents by following the
guidelines, and serving them as text/html. Therefore, documents served as
text/html should be treated as HTML and not as XHTML.
It's a very common pitfall, because W3C Validator largely ignores that rule, but browsers follow it religiously. Read
Understanding HTML, XML and XHTML from WebKit blog:
In fact, the vast majority of supposedly XHTML documents on the internet are served as text/html
. Which means they are not XHTML at all, but actually invalid HTML that’s getting by on the error handling of HTML parsers. All those “Valid XHTML 1.0!” links on the web are really saying “Invalid HTML 4.01!”.
To test whether you have real XHTML or invalid HTML with XHTML's DOCTYPE, put this in your document:
<span style="color:green"><span style="color:red"/>
If it's red, it's HTML. Green is XHTML.
</span>
It validates, and in real XHTML it works perfectly (see: 1 vs 2). If you can't believe your eyes (or don't know how to set MIME types), open your page via XHTML proxy.
Another way to check is view source in Firefox. It will highlight slashes in red when they're invalid.
In HTML5/XHTML5 this hasn't changed, and the distinction is even clearer, because you don't even have additional DOCTYPE
. Content-Type
is the king.
For the record, the XHTML spec allows any element to be self-closing by making XHTML an XML application: [emphasis mine]
Empty-element tags may be used for any element which has no content, whether or not it is declared using the keyword EMPTY.
It's also explicitly shown in the XHTML spec:
Empty elements must either have an end tag or the start tag must end with />
. For instance, <br/>
or <hr></hr>
In the question, there existed a race condition between:
- The browser's attempt to initialize the drop-down list, ready to have its selected index updated, and
- Your code to set the selected index
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.
Best Solution
XHTML 1 specification says:
С.3. Element Minimization and Empty Element Content
XHTML DTD specifies script elements as: