Validweb

<select> bug in IE

Tuesday 16 March 2004

Note: this article was published over 4 years ago. Techniques, tools or technologies described in this article could be outdated. Please help me by notifying me of any broken links you might encounter.

“Selecteer uit bovenstaande lijst”

Dit hebben de programmeurs van Internet Explorer waarschijnlijk iets te letterlijk genomen. Er zit namelijk een fout in Internet Explorer die ervoor zorgt dat <select> elementen (vaak combobox of selectbox genoemd) altijd boven aan in de stacking order (de volgorde waarop elementen getekend worden in de browser) komen. Ik kwam dit probleem tegen tijdens het implementeren van ‘Suckerfish Dropdowns’ in een project voor een klant. De <select> elementen vallen boven elk ander element op de pagina, waardoor in dit geval het menu onbruikbaar wordt, aangezien het menu verdwijnt zodra je met de muis over het <select> element beweegt. Daar komt nog bij dat het er natuurlijk niet uit ziet.

Illustratie van het probleem

bekijk voorbeeld 1
figuur 1: <select> bug demo in IE 6

Zoals je in dit voorbeeld kunt zien valt het menu onder de <select>, ook al heeft het menu een z-index (een waarde waarmee de positie binnen de stacking order wordt aangegeven) die hoger is dan die van het <select> element. Het menu valt in IE wel over de andere elementen in de pagina. Dit geeft aan dat Internet Explorer de z-index voor het <select> element niet juist interpreteert.

Na enig zoeken vond ik op de site van Microsoft een artikel dat dit probleem beschrijft. Het probleem doet zich voor omdat IE onderscheid maakt tussen verschillende soorten element, windowed en windowless elementen. Windowed elementen zijn elementen die op een aparte laag bovenop de rest van de pagina worden getekend. Het <select> element behoort dus tot deze groep en wordt boven alle windowless elementen getekend.

Wat nu?

Een echte oplossing voor dit probleem is er niet, windowed elementen worden altijd boven windowless elementen getekend. De enige workaround lijkt om de <select> elementen te verbergen op het moment dat een windowless bovenaan in de stacking order moet komen, zodat ons windowless element bovenaan lijkt te staan. Hetzelfde wordt door Microsoft’s dr. GUI aangeraden aan een gebruiker met hetzelfde probleem.

Aangezien de methode beschreven in ‘Suckerfish Dropdowns’ gebruikt maakt van Javascript, leek mij het logisch een functie die automatisch alle <select> elementen verbergt in het Suckerfish script te integreren.

De functies

Er zijn 2 functies nodig: selectHide zorgt voor het verbergen van de selects, en je raadt het al, selectShow tovert ze weer netjes op het scherm.


function selectHide(){
	selects = document.getElementsByTagName("select");
	for (i = 0; i != selects.length; i++) {
		selects[i].style.visibility = "hidden";
	}
}
function selectShow(){
	selects = document.getElementsByTagName("select");
	for (i = 0; i != selects.length; i++) {
		selects[i].style.visibility = "visible";
	}
}

Let op: Deze functies hebben effect op alle <select> elementen op de gehele pagina, dus ook die elementen die ons menu helemaal niet weg in de weg zitten. Je kunt deze functies uiteraard zo aanpassen dat het bijvoorbeeld alleen de elementen die jij aangeeft door middel van een id of class verbergt. Bovendien zou je een functie kunnen inbouwen die naar de coordinaten van het element op het scherm kijkt, en alleen de elementen verbergt die het menu in de weg zitten.

Het invoegen van deze functies in het ‘Suckerfish Dropdown’ script is simpel, het gedeelte waar we onze functies aanroepen ziet er als volgt uit:


if (node.nodeName=="LI") {
	node.onmouseover=function() {
		this.className+=" over";
		selectHide();
	}
	node.onmouseout=function() {
		this.className=this.className.replace(" over", "");
		selectShow();
	}
}

Conclusie

bekijk voorbeeld 2
figuur 2: <select> bug fixed in IE 6

Zoals je kunt zien in de uiteindelijke demo is het meer een tijdelijke noodoplossing dan een bugfix. Er lijkt weinig aan te doen, en er zit waarschijnlijk niks anders op dan wachten tot Microsoft de bug uit de browser haalt. Er is nog een andere workaround gevonden door de jongens van DotNetJunkies, maar deze oplossing vind ik persoonlijk te ingrijpend, het vervuild de html teveel met semantisch incorrecte codes.

Update (2 november 2004): iG.Studio komt met een elegante manier om de DotNetJunkies’ fix toe te passen, het iframe wordt via Javascript toegevoegd, hierdoor wordt je html code niet onnodig vervuild.

« Validweb Ik wil ook een site: Introductie »