Scrolling in Select Box fires onchange

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

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 1024 Updated to add a wrapper around onfocus().

Subscribe via RSS ı Email
Jehiah Czebotar