Pierpaolo
Pierpaolo

Reputation: 559

Onchange in Firefox is triggered without changing

I have a select, for which a onchange event is set.
The problem is, in Firefox only (FF v. 12), that the onchange event is triggered even if the user does not click on any option; just hovering the option it is enough to trigger it.

i.e.: If the user clicks on the select, hovers one of the options and then he clicks outside the select, the value of the select changes (even if the shown value does not) thus the event is triggered.

This does not happen if one of elements of the select is already selected. The behavior is more or less the same as in this Mozilla bug: https://bugzilla.mozilla.org/show_bug.cgi?id=265047

Upvotes: 3

Views: 3928

Answers (1)

Shadow Wizzard
Shadow Wizzard

Reputation: 66388

This is certainly a bug in Firefox that assign the selected value and selected index upon hovering the items, when there is no selected index defined.

While I can't fix the bug, one workaround that is pretty simple and working is adding empty and hidden item to the list to be the first item and assigning it as the selected item.

For example:

<select id="mySelect">
    <option value="" style="display: none;"></option>
    <option value="1">first</option>
    <option value="2">second</option>
</select>

The user won't see any change and when you "clear" the selection, assign selected index of 0 instead of -1 e.g.

var oDDL = document.getElementById("mySelect");
oDDL.selectedIndex = 0;

Live test case - behaves properly even on Firefox now.

Update - The above code is not working properly in IE8 as it still showing the first empty option. To solve this, it's possible to simply remove the option in all browsers that support it when the browser is not Firefox. Updated code will be:

navigator.sayswho = (function(){
    var N = navigator.appName, ua= navigator.userAgent, tem;
    var M = ua.match(/(opera|chrome|safari|firefox|msie)\/?\s*(\.?\d+(\.\d+)*)/i);
    if (M && (tem = ua.match(/version\/([\.\d]+)/i)) != null) M[2] = tem[1];
    M = M? [M[1], M[2]]: [N, navigator.appVersion, '-?'];
    return M;
})();

window.onload = function() {
    var oDDL = document.getElementById("mySelect");
    oDDL.selectedIndex = 0;
    var blnFirefox = (navigator.sayswho[0].toLowerCase().indexOf("firefox") >= 0);
    if (!blnFirefox && oDDL.remove) {
        oDDL.remove(0);
        oDDL.selectedIndex = -1;
    }
    oDDL.onchange = function() {
        alert("hello");
    };
};

The function that identifies the browser was taken from this answer.

Updated fiddle - working in Firefox, Chrome, IE9 and IE8.

Upvotes: 1

Related Questions