In IE when you use the scrollwheel on your mouse it moves the page up and down.. right? wrong. When you are focused on a select box is scrolls through the options - firing off onchange events for every option you view. That can be a problem because you scroll pretty quick, and it will easily tie up the browser if you are using any fun web 2.0 scripts that trigger on a select box’s onchange event.
I have an example page of the problem and solution
I have come up with the following behaviour.js workaround. Hopefully you’ll find it useful.
How the Fix Works The problem is when the onchange event runs multiple times in a row without intermediate onclick events. So we just wrap the events of the select element and catch that case.
We wrap the onchange event to set a flag when it runs; and if the flag is already set : unregister itself temporarily. Then we just clear the flag onclick and onblur. We also re-set the onchange function onblur (if necessary).
Lastly this script does a dom check so the fix is only applied in IE.
[js]
function switchfunctions(el){
el._scrolling = el.onchange;
el.onchange = null;
}
var scrollfix = {
'select' : function (el){
if ( typeof(document.media)=='string'){// dom check for IE
// grab the real functions
el.scrollonchange = el.onchange ? el.onchange : function(){return true;};
el.scrollonclick = el.onclick ? el.onclick : function(){return true;};
el.scrollonblur = el.onblur ? el.onblur : function(){return true;};
el.scrollonfocus = el.onfocus ? el.onfocus : function(){return true;};
// make a new onchange which will switch if it's fired twice in a row before onclick or onblur
el.onchange = function(){
debug("new onchange");
if (this.scrolling && this.scrollingfix){switchfunctions(this);return false;}
if (this.scrollingfix){this.scrolling=true;}
el.scrollonchange();
}
// now set the flag so we know this happened between onchange()'s
el.onfocus = function(){
this.scrolling = false; // set flag
this.scrollingfix = true;
this.scrollonfocus();
}
// now set the flag so we know this happened between onchange()'s
el.onclick = function(){
this.scrolling = false; // set flag
this.scrollingfix = true;
this.scrollonclick();
}
// set flag so we know this happened between scrolling && re-set the onchange if needed
el.onblur = function(){
if (this._scrolling){
this.scrolling = false; // set flag so orignal onchange is happy
this.onchange = this._scrolling; // unswitch functions
this.onchange();
this._scrolling = false;
}
this.scrolling = false; // set flag
this.scrollingfix = false;
this.scrollonblur(); // run original funciton
}
}
}
};
Behaviour.register(scrollfix);
[/js]
Adding small behaviour scripts is a useful approach for “fixing” browsers. It’s something I also used when working around the autocomplete not firing onchange problem I identified last week.
Thanks M$ for wasting another day of my life.
Update 10⁄24 Updated to add a wrapper around onfocus().