Internet Explorer doesn’t just suck, it also blows!
I’m spending most of my time these days working on SitePoint’s upcoming Ultimate JavaScript Reference, a task that I can fairly say is eating my brain.
Unlike the authors of the imminent Ultimate CSS Reference, I didn’t have any particular inclination to be nice to Internet Explorer. And I knew I was going to run into bugs and quirks, none of which would be any different in IE7, because the DOM simply wasn’t on the development radar for that version.
Even so, I’ve been nothing short of staggered at the sheer amount of chaotic brokenness evident in its implementation of even the simplest of things.
You may remember, not so long ago, that I wrote about the behavior of href
attributes in Internet Explorer, and how for links they come back as qualified URIs rather than literal attribute values. But, oh man … that is so the tip of the iceberg when it comes to getAttribute()
…
You wouldn’t have thought it was so hard
In addition to qualifying the value of href
attributes on links, IE does the same thing for the src
attribute of images.
When retrieving a style
attribute, IE returns a style
object, rather than an attribute value. Retrieving an event-handling attribute such as onclick
, it returns the contents of the event handler wrapped in an anonymous function. Retrieving an attribute value which evaluates to boolean true
(such as disabled
or checked
, when defined) it returns a boolean, and retrieving a value that evaluates to a number (such as tabindex
), it returns a number. All of these values are supposed to be returned as strings.
But these attributes are considered by IE to have non-string values; and so if they’re not defined at all they return null
, rather than an empty string. IE also returns null
for non-defined attributes it doesn’t recognise (ie. custom attribute names).
In its defense, other non-defined but known attributes correctly return an empty string, which is according to specification; and IE is actually the only browser that does this (Firefox, Opera and Safari all return null
). But that’s not really much of a defense, because it only does that for attributes it recognises — so it isn’t really implementing to specification, it just happens to be correct!
Pure class
To retrieve a class
attribute in Internet Explorer you must refer to it as className
; to retrieve a for
attribute you must refer to it as htmlFor
:
//these work in IE, null in others
element.getAttribute('className');
element.getAttribute('htmlFor');
Now this is a side-effect of the mapping of attributes to HTML DOM properties — for example, as a DOM property you always have to refer to element.className
rather than element.class
, because class
is a reserved word in JavaScript. But while other browsers reconcile this by allowing string values to getAttribute()
to use the original attribute name, Internet Explorer does not:
//these work in others, null in IE
element.getAttribute('class');
element.getAttribute('for');
And there are other attributes that can only be referred to by the camel-cased name they use for their DOM property equivalent, even though those names are not reserved words; I haven’t found a concrete pattern, but examples of this are tabIndex
and accessKey
.
And there’s more …
Internet Explorer implements a second, proprietary argument to getAttribute()
, which is supposed to control the way it behaves. The second argument is a numerical flag which can take the value 0
, 1
or 2
. According to MSDN:
-
0
(default): Performs a property search that is not case-sensitive, and returns an interpolated value if the property is found. -
1
: Performs a case-sensitive property search. -
2
: Returns the value exactly as it was set in script or in the source document.
When it says interpolated value
it means it won’t necessarily return a string, as already noted. Notice also how it says if the property is found
[my emphasis] — this would seem to imply that IE is not using getAttribute()
as a getter for node values at all, it’s using it as a getter for DOM properties! If true, this goes a long way to explaining its aberrant behavior — if it’s retrieving property values, that’s why it requires property names, and why it returns a value of the applicable type; and when MSDN says that getAttribute()
retrieves the value of the specified attribute
, it is flat-out lying.
The difference between 0
and 1
appears to be implemented as documented — attribute names are treated as case-sensitive, so a search for onClick
will not match onclick
.
However the value 2
does not behave as documented. When this value is used, event-handling attributes are still returned as functions, the style
attribute is an empty string, and values which evaluate to boolean true
return 65535
(which is 216
, the largest possible value of a 16-bit number. What’s up with that??) But hey — on a more positive note — href
and src
attributes do return their literal value, rather than a qualified URI. I suppose we should be grateful for small mercies!
You can see why I said it’s eating my brain … I mean, failing so comprehensively to implement the standards is one thing, and bad enough, but Internet Explorer doesn’t even implement its own proprietary stuff correctly!