This case is mentioned in the HTML5 spec:
On setting, the selectedIndex
attribute must set the selectedness of all the option elements in the list of options to false, and then the option element in the list of options whose index is the given new value, if any, must have its selectedness set to true and its dirtiness set to true.
Note: This can result in no element having a selectedness set to true even in the case of the select element having no multiple attribute and a display size of 1.
...
If nodes are inserted or nodes are removed causing the list of options to gain or lose one or more option elements, or if an option element in the list of options asks for a reset, then, if the select element's multiple attribute is absent, the select element's display size is 1, and no option elements in the select element's list of options have their selectedness set to true, the user agent must set the selectedness of the first option element in the list of options in tree order that is not disabled, if any, to true.
Changing an option via setting its innerHTML
or textContent
property triggers this reset (except on Firefox), but the text
property (which is <option>
only) does not trigger it (except on IE).
// these triggers the <select> element's reset (except on Firefox)
$("#three")[0].innerHTML = "foo";
$("#three")[0].textContent = "foo";
// this does not trigger the reset (except on IE)
$("#three")[0].text = "foo";
Firefox follows the spec more strictly, it only resets the <select>
if there is a new <option>
, or there was a removal of one of the <option>
s. But it fails to execute the reset during setting an <option>
's selected
property to false (but that should trigger the reset too).
In short, all of the current browsers fail to implement the spec completely, so the only cross-platform workaround is to change selectedIndex
as the last operation on a select (and its descendant elements):
$("#three").html("moo");
$(".drpmnu").prop("selectedIndex", -1);