Scrolling in Select Box fires onchange

by @jehiah on 2005-10-21 18:42
Filed under: All, HTML, IE, Javascript

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.

function switchfunctions(el){
   el._scrolling = el.onchange;
   el.onchange = null;

var scrollfix = {
'select' : function (el){
   if ( typeof('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;}

     // now set the flag so we know this happened between onchange()'s
     el.onfocus = function(){
    this.scrolling = false; // set flag
    this.scrollingfix = true;

     // now set the flag so we know this happened between onchange()'s
     el.onclick = function(){
    this.scrolling = false; // set flag
    this.scrollingfix = true;

     // 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._scrolling = false; 
    this.scrolling = false; // set flag
    this.scrollingfix = false;
    this.scrollonblur(); // run original funciton

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().

Subscribe via RSS ı Email
© 2016 - Jehiah Czebotar