W3C DOM Compatibility - Core

Last major update on 21 March 2008.

You can also view the previous version, which was created in August 2005 and still features IE Mac.

Cover of my book

If you'd like to have some practical examples of what you can do with the W3C DOM, read my book ppk on JavaScript, especially chapter 8.

These compatibility tables detail support for the W3C DOM Core Level 1 and 2 modules in all modern browsers.

On this page I grouped the various W3C DOM methods and properties in eight tables. Basically you must know the first four tables by heart and you'll rarely need the second four tables.

  1. The Five Methods with which the W3C DOM starts. Creating and finding HTML elements.
  2. Node information. Once you found a node you need more information about it.
  3. Walking the DOM tree. How to go from one node to another.
  4. Node manipulation. How to move nodes through the document.
  5. Manipulating data. Data is always text, and there are some specialized methods for dealing with it.
  6. Manipulating attributes. Terrible browser incompatibilities.
  7. Miscellaneous methods and properties. You'll rarely need one of them.
  8. Microsoft extensions to Level 1 DOM Core. Generally not interesting.

The Five Methods

First of all the Five Methods. The average W3C DOM script uses four of them; and the only reason the fifth isn't used, too, is its browser compatibility pattern.

The first two methods allow you to create element nodes and text nodes. Later you insert these newly created nodes into the document. The second three methods are for finding elements in the page. You can either find a single one, identified by an id, or all tags of one type.

You must know these methods by heart.

Method or property IE 5.5 IE 6 IE 7 IE8b1 FF 2 FF 3b5 Saf 3.0 Win Saf 3.1 Win Opera 9.26 Opera 9.5b Konqueror 3.5.7
createElement()
Create a new element

Test page
Yes Yes Yes Yes Yes
var x = document.createElement('P')
Create a new HTML element node <P> and temporarily place it in x, which is later inserted into the document.
  • IE also supports ('<P>').
createTextNode()
Create a new text node

Test page
Yes Yes Yes Yes Yes
var x = document.createTextNode('text')

Create a text node with content text and temporarily place it in x, which is later inserted into the document.

getElementById()
Get the element with this ID

Test page Lower case 'd'!!
Almost Yes Yes Yes Almost Yes Yes
var x = document.getElementById('test')

Take the element with id="test" (wherever it is in the document) and put it in x.

If there is more than one element with id="test", the method selects the first in the document. All others are ignored.

  • IE7- and Opera 9.26 also return the element with name="test".
Method or property IE 5.5 IE 6 IE 7 IE8b1 FF 2 FF 3b5 Saf 3.0 Win Saf 3.1 Win Opera 9.26 Opera 9.5b Konqueror 3.5.7
getElementsByClassName()
Get a nodeList of the elements with this class.

Test page
No No Yes No Yes No Yes No
document.getElementsByClassName('test')
document.getElementsByClassName('test test2')

The first expression returns a nodeList with all elements that have a class value that contains "test". The second one returns a nodeList will all elements that have a class value that contains both "test" and "test2" (in any order).

getElementsByTagName()
Get all tags of this type

Test page
Incomplete Yes Yes Yes Yes Incomplete
var x = document.getElementsByTagName('P')

Make x into a nodeList of all P's in the document, so x[1] is the second P etc.

var x = y.getElementsByTagName('P')

Gets all paragraphs that are descendants of node y.

  • The * argument, which ought to select all elements in the document, doesn't work in IE 5.5.
  • Custom tags are not returned in Konqueror.
Method or property IE 5.5 IE 6 IE 7 IE8b1 FF 2 FF 3b5 Saf 3.0 Win Saf 3.1 Win Opera 9.26 Opera 9.5b Konqueror 3.5.7

Node information

These four properties give basic information about all nodes. What they return depends on the node type. They are read-only, except for nodeValue.

There are three basic node types: element nodes (HTML tags), attribute nodes and text nodes. I test these properties for all these three types and added a fourth node type: the document node (the root of all other nodes).

You must know these properties by heart.

Method or property IE 5.5 IE 6 IE 7 IE8b1 FF 2 FF 3b5 Saf 3.0 Win Saf 3.1 Win Opera 9.26 Opera 9.5b Konqueror 3.5.7
nodeName
The name of the node

Test page
Incomplete Yes Yes Yes Yes Almost
x.nodeName

The name of node x. The correct names are:

Element Attribute Text Comments Document
the UPPER CASE tag name the attribute name #text #comment #document
  • IE 5.5 doesn't support a nodeName for attributes and the document.
  • IE 5.5 reports the nodeName of a comment as !.
  • Konqueror doesn't see comment nodes.
nodeType
The type of the node

Test page
Incomplete Yes Yes Yes Yes Almost
x.nodeType

The type of node x. The correct types are:

Element Attribute Text Comments Document
1 2 3 8 9
  • IE 5.5: attributes and document not defined; comment has nodeType 1
  • Konqueror doesn't see comment nodes.
nodeValue
The value of the node, if any. Read/write

Test page
Incomplete Yes Yes Yes Yes Almost
x.nodeValue

Get the value of node x

x.nodeValue = 'Test'

Set the value of node x

Element Attribute Text Comments Document
n/a Value of attribute Content of text node Content of comment node n/a
  • IE 5.5 doesn't support nodeValue for attributes
  • Konqueror doesn't see comment nodes.
tagName
The tag name of an element node

Test page Don't use
Almost Yes Yes Yes Yes
x.tagName

Get the tag name of node x. Correct values are:

Element Attribute Text Comments Document
the UPPER CASE tag name n/a n/a n/a n/a

My advice is not to use tagName at all.
nodeName contains all functionalities of tagName, plus a few more. Therefore nodeName is always the better choice.

  • In IE (all versions) the tagName of a comment node is !
Method or property IE 5.5 IE 6 IE 7 IE8b1 FF 2 FF 3b5 Saf 3.0 Win Saf 3.1 Win Opera 9.26 Opera 9.5b Konqueror 3.5.7

The DOM tree

Five properties and two arrays for walking through the DOM tree. Using these properties, you can reach nodes that are close to the current node in the document structure.

In general you shouldn't use too many of these properties. As soon as you're doing something like

x.parentNode.firstChild.nextSibling.children[2]

your code is too complicated. Complex relationships between nodes can suddenly and unexpectedly change when you alter the document structure, and altering the document structure is the point of the W3C DOM. In general you should use only one or two of these properties per action.

You must know these properties by heart.

Method or property IE 5.5 IE 6 IE 7 IE8b1 FF 2 FF 3b5 Saf 3.0 Win Saf 3.1 Win Opera 9.26 Opera 9.5b Konqueror 3.5.7
childNodes[]
An array with all child nodes of the node

Test page
Yes Yes Yes Yes Almost
x.childNodes[1]

Get the second child node of node x.

The childNodes nodeList consists of all child nodes of the element, including (empty) text nodes and comment nodes.

  • IE does not count empty text nodes. Since this is the desired behaviour as far as I'm concerned, it still gets a Yes.
  • Konqueror ignores comment nodes.
children[]
An array with all child element nodes of the node

Test page
Almost No Yes Yes Yes
x.children[1]

Get the second element child node of node x.

Where childNodes holds all child nodes, children only holds those that are element nodes (HTML tags).

  • IE incorrectly counts comment nodes, too.
firstChild
The first child node of the node

Test page
Yes Yes Yes Yes Almost
x.firstChild

Get the first child node of node x.

  • Konqueror ignores comment nodes.
hasChildNodes()
Check if the node has child nodes

Test page
Yes Yes Yes Yes Yes
x.hasChildNodes()

Returns true when node x has child nodes; false when it hasn't.

Method or property IE 5.5 IE 6 IE 7 IE8b1 FF 2 FF 3b5 Saf 3.0 Win Saf 3.1 Win Opera 9.26 Opera 9.5b Konqueror 3.5.7
lastChild
The last child node of the node

Test page
Yes Yes Yes Yes Almost
x.lastChild

Get the last child of node x.

  • Konqueror ignores comment nodes.
nextSibling
The next sibling node of the node

Test page
Yes Yes Yes Yes Almost
x.nextSibling

Get the next child of the parent of x.

  • Konqueror ignores comment nodes.
parentNode
The parent node of the node

Test page
Yes Yes Yes Yes Yes
x.parentNode

Get the parent node of x.

previousSibling
The previous sibling node of the node

Test page
Yes Yes Yes Yes Almost
x.previousSibling

Get the previous child of the parent of x.

  • Konqueror ignores comment nodes.
sourceIndex
The index number of the node in the page source

Test page
Yes No No Incorrect Yes Yes
x.sourceIndex

Get the sourceIndex of element x. This is also the index number for the element in the document.getElementsByTagName('*') array.

  • Opera 9.26 returns the wrong sourceIndex in my test.
Method or property IE 5.5 IE 6 IE 7 IE8b1 FF 2 FF 3b5 Saf 3.0 Win Saf 3.1 Win Opera 9.26 Opera 9.5b Konqueror 3.5.7

Node manipulation

These five methods allow you to restructure the document. The average DOM script uses at least two of these methods.

The changes in the document structure are applied immediately, the whole DOM tree is altered. The browser, too, will immediately show the changes.

You must know these methods by heart.

Method or property IE 5.5 IE 6 IE 7 IE8b1 FF 2 FF 3b5 Saf 3.0 Win Saf 3.1 Win Opera 9.26 Opera 9.5b Konqueror 3.5.7
appendChild()
Append a child node as the last node to an element

Test page
Yes Yes Yes Yes Yes
x.appendChild(y)

Make node y the last child of node x.

If you append a node that's somewhere else in the document, it moves to the new position.

cloneNode()
Clone a node

Test page
Yes Yes Yes Yes Yes
x = y.cloneNode(true | false)

Make node x a copy of node y. If the argument is true, the entire tree below y is copied, if it's false only the root node y is copied.

Later you insert the clone into the document.

insertBefore()
Insert a node into the child nodes of an element

Test page
Yes Yes Yes Yes Yes
x.insertBefore(y,z)

Insert node y as a child of node x just before node z.

removeChild()
Remove a child node from an element

Test page
Yes Yes Yes Yes Yes
x.removeChild(y)

Remove child y of node x.

replaceChild()
Replace a child node of an element by another child node

Test page
Yes Yes Yes Yes Yes
x.replaceChild(y,z)

Replace node z, a child of node x, by node y.

Method or property IE 5.5 IE 6 IE 7 IE8b1 FF 2 FF 3b5 Saf 3.0 Win Saf 3.1 Win Opera 9.26 Opera 9.5b Konqueror 3.5.7

Data

These methods are for manipulating text data. Note the difference between a text node and text data: the text node is a node and contains the data in its nodeValue. The methods below only work with this contained data.

Method or property IE 5.5 IE 6 IE 7 IE8b1 FF 2 FF 3b5 Saf 3.0 Win Saf 3.1 Win Opera 9.26 Opera 9.5b Konqueror 3.5.7
appendData()
Append data to a text node

Test page
No Yes Yes Yes Yes Yes
x.appendData(' some extra text')

Appends the string some extra text to x, which must be a text node.

data
The content of a text node

Test page
Yes Yes Yes Yes Yes
x.data

The content of x, which must be a text node. The same as x.nodeValue.

Can also be set:

x.data = 'The new text'
deleteData()
Delete text from a text node

Test page
No Yes Yes Yes Yes Yes
x.deleteData(4,3)

Delete some data from x, which must be a text node, starting at the fifth character and deleting three characters. Second argument is required.

insertData()
Insert text into a text node

Test page
No Yes Yes Yes Yes Yes
x.insertData(4,' and now for some extra text ')

Insert the string and now for some extra text after the fourth character into x, which must be a text node.

replaceData()
Replace text in a text node

Test page
No Yes Yes Yes Yes Yes
x.replaceData(4,3,' and for some new text ')

Replace three characters, beginning at the fifth one, of node x, which must be a text node, by the string and for some new text.

substringData()
Take a substring of the text in the text node

Test page
No Yes Yes Yes Yes Yes
x.substringData(4,3)

Takes a substring of x, which must be a text node, starting at the fifth character and with a length of three characters. Thus it's the same as the old substr() method of strings.

Method or property IE 5.5 IE 6 IE 7 IE8b1 FF 2 FF 3b5 Saf 3.0 Win Saf 3.1 Win Opera 9.26 Opera 9.5b Konqueror 3.5.7

Attributes

A bloody mess. Try influencing attributes in this order:

  1. Try getting or setting a specific property, like x.id or y.onclick.
  2. If there is no specific property, use getAttribute() or setAttribute().
  3. If even that doesn't work, try any other method or property in the table below. Most have horrible browser incompatibility patterns, though.
  4. Avoid attributes[]. It's worse than anything else.

In my view any method or property concerning attribute nodes should also work on the style attribute, event handlers and custom attributes. If not I judge the method or property incomplete.

Method or property IE 5.5 IE 6 IE 7 IE8b1 FF 2 FF 3b5 Saf 3.0 Win Saf 3.1 Win Opera 9.26 Opera 9.5b Konqueror 3.5.7
attributes[index]
An array with the attributes of a node, accessed by index number, in the order they're defined in the source code

Test page Do not use Use getAttribute() instead
Alternative Buggy Incorrect Yes Yes Yes
x.attributes[1]

This array consists of all defined attributes in all browsers save IE, where it consists of all attributes that can possibly be defined on the node (84 all in all).

Do yourself a favour and don't use the indexed attributes array.

  • Safari, Opera, Konqueror take the second attribute that's defined on node x (align in the test).
  • Firefox tries to do the same, but the order of attributes is off.
  • IE takes the second possible attribute of node x (dataFld in the test), whether it's defined or not.
  • IE 5.5 initially gives the value of the attribute; not the attribute object.
  • In IE8b1 the attributes array doesn't have a length.
attributes[key]
An array with the attributes of a node, accessed by attribute name

Test page
Incorrect Almost Yes Yes Yes Yes No
x.attributes['align']

Get the align attribute object of node x. If the node has no align attribute, it returns undefined (except in IE, where it returns an attribute object that has no value.)

After years in the wilderness attribute[key] is slowly approaching a workable situation. I used to advice you not to use it; but by now you can try it if you like.

  • IE7- doesn't return the value of a style attribute.
  • IE 5.5 doesn't return custom attributes, and initially gives the attribute value instead of an attribute object.
createAttribute() and setAttributeNode()
Create a new attribute node and append it to an element node.

Test page
No Yes Yes Yes Yes Yes
z = document.createAttribute('title');
z.value = 'Test title';
x.setAttributeNode(z)

This creates a title attribute with a value and sets it on node x.

Method or property IE 5.5 IE 6 IE 7 IE8b1 FF 2 FF 3b5 Saf 3.0 Win Saf 3.1 Win Opera 9.26 Opera 9.5b Konqueror 3.5.7
getAttribute()
Get the value of an attribute

Test page
Almost Yes Yes Yes Yes
x.getAttribute('align')

Gives the value of the align attribute of node x.

  • In IE, accessing the style attribute gives an object, and accessing the onclick attribute gives an anonymous function wrapped around the actual content.
getAttributeNode()
Get an attribute node

Test page
No Almost Yes Yes Yes Yes Yes
x.getAttributeNode('align')

Get the attribute object align of node x. This is an object, not a value.

  • IE 6/7 don't allow you to access the value of x.getAttributeNode('style').
hasAttribute()
Check if a node has a certain attribute

Test page
No Almost Yes Yes Yes Yes
x.hasAttribute('align')

Returns true when node x has an align attribute, false when it hasn't.

  • IE8b1 returns false when asked for the style attribute, even though it's defined.
hasAttributes()
Check if a node has attributes

Test page
No Yes Yes Yes Yes
x.hasAttributes()

Returns true when node x has attributes, false when it hasn't.

name
The name of an attribute

Test page
No Yes Yes Yes Yes Yes
x.name

The name of attribute node x.

Method or property IE 5.5 IE 6 IE 7 IE8b1 FF 2 FF 3b5 Saf 3.0 Win Saf 3.1 Win Opera 9.26 Opera 9.5b Konqueror 3.5.7
removeAttribute()
Remove an attribute node

Test page
Almost Yes Yes Almost Almost
x.removeAttribute('align')

Remove the align attribute from node x.

  • IE and Opera don't remove event handlers.
  • Konqueror doesn't remove the align attribute.
removeAttributeNode()
Remove an attribute node

Test page
No Minimal Incomplete Yes Yes Almost Almost
x.removeAttributeNode(x.attributes['align'])
x.removeAttributeNode(x.attributes[1])
x.removeAttributeNode(x.getAttributeNode('align'))

Removes the attribute node. There is little difference with removeAttribute(), except in the method argument.

  • IE 6 does't remove anything, but doesn't give an error message either.
  • IE 7/8b1 doesn't remove styles and event handlers.
  • Opera doesn't remove event handlers.
  • Konqueror doesn't remove the align attribute.
setAttribute()
Set the value of an attribute

Test page
Incomplete Almost Yes Yes Yes Yes
x.setAttribute('align','right')

Set the align attribute of node x to right. The name and value are both strings.

  • IE5-7 doesn't set styles and removes events when you try to set them.
  • IE8b1 doesn't set event handlers.
setAttributeNode()
See createAttribute()
value
The value of an attribute

Test page
No Almost Yes Yes Yes Yes
x.value

The value of attribute x.

  • IE gives null for style values.
Method or property IE 5.5 IE 6 IE 7 IE8b1 FF 2 FF 3b5 Saf 3.0 Win Saf 3.1 Win Opera 9.26 Opera 9.5b Konqueror 3.5.7

Miscellaneous

A lot of miscellaneous methods and properties that you'll rarely need. I use only two of them in an actual script.

Method or property IE 5.5 IE 6 IE 7 IE8b1 FF 2 FF 3b5 Saf 3.0 Win Saf 3.1 Win Opera 9.26 Opera 9.5b Konqueror 3.5.7
contains()
Check whether an element contains another element

Test page
Yes No Yes Yes Yes
x.contains(y)

If node y is a descendant of node x, the method returns true, else false.

createDocument()
Create a new document

Test page
No Yes Yes Yes Yes
x = document.implementation.createDocument('','',null)

Creates a new document. The the Import XML script gives an example of what to do with such a document.

createDocumentFragment()
Create a document fragment

Test page
No Yes Yes Yes Yes Yes
x = document.createDocumentFragment();
x.[fill with nodes];
document.[somewhere].appendChild(x);

Create a fragment, add a lot of nodes to it, and then insert it into the document. Note that the fragment itself is not inserted, only its child nodes.

You may not move a node from the existing document to the document fragment. (Cloning is allowed, however.)

documentElement
The HTML tag

Test page
Yes Yes Yes Yes Yes
document.documentElement

Represents the root element of the XML document. In any HTML document, the <html> element is of course the root element.

getElementsByName()
Get elements by their name attribute

Test page
Incorrect and incomplete Incomplete Yes Yes Incorrect Incomplete
var x = document.getElementsByName('test')

Create a nodeList with all elements that have name="test". It should ignore elements with id="test"

On my test page the <p>, <input>, <img> and <ppk> tags have this name, while there's also a paragraph with id="test". Ideally, all browsers should get the first four elements and ignore the fifth one.

  • IE5-7 and Opera 9.26 ignore the <p> and <ppk> tags with name="test", but counts the <p> with id="test"
  • IE8b1 ignores the <ppk> tag.
  • Opera counts the <p> with id="test"
  • Konqueror ignores the <ppk> tag.
Method or property IE 5.5 IE 6 IE 7 IE8b1 FF 2 FF 3b5 Saf 3.0 Win Saf 3.1 Win Opera 9.26 Opera 9.5b Konqueror 3.5.7
hasFeature()
Check if a document has a certain feature.

Test page
No Yes Yes Yes Yes Yes
document.implementation.hasFeature('XML','1.0')

Returns true if the browser considers itself to be supporting XML 1.0. Other values include Core, HTML, Range, and CSS.

Note that this method reports the browser's own assessment of its capabilities. There is no independent check.

isSupported()
Check if an element has a certain feature.

Test page
No Yes Yes Yes Yes
x.isSupported('XML','1.0')

Returns true if the browser considers itself to be supporting XML 1.0. Other values include Core, HTML, Range, and CSS.

Note that this method reports the browser's own assessment of its capabilities. There is no independent check.

item()
Access an item in an array

Test page Not necessary in JavaScript
Yes Yes Yes Yes Yes
document.getElementsByTagName('P').item(0)

The same as document.getElementsByTagName('P')[0].

The item() method is meant for other programming languages where nodeLists like those returned by getElementsByTagName are not conveniently accessible as if they were arrays.

You don't need item() at all in JavaScript.

normalize()
Merge adjacent text nodes into one node

Test page
No Yes Yes Yes Yes Yes
x.normalize()

All child nodes of node x that are text nodes and have other text nodes as siblings, are merged. This is in fact the reverse of splitText: text nodes that were split, come together again.

ownerDocument
The document that 'owns' the element

Test page
No Yes Yes Yes Yes Yes
x.ownerDocument

Refers to the document object that 'owns' node x. This is the document node.

splitText()
Split a text node into two text nodes

Test page
Yes Yes Yes Yes Yes
x.splitText(5)

Split the text node x at the 6th character. x now contains the first part (char. 0-5), while a new node is created (and becomes x.nextSibling) which contains the second part (char. 6-end) of the orginial text.

Method or property IE 5.5 IE 6 IE 7 IE8b1 FF 2 FF 3b5 Saf 3.0 Win Saf 3.1 Win Opera 9.26 Opera 9.5b Konqueror 3.5.7

Microsoft extensions

As usual Microsoft has extended the standard somewhat. Though sometimes its extensions are brilliant (innerHTML springs to mind), in the case of the DOM Core they aren't.

Note the difference between W3C and Microsoft methods. The W3C methods are owned by the parent element of the node you want to adjust, the Microsoft methods by the node itself.

Method or property IE 5.5 IE 6 IE 7 IE8b1 FF 2 FF 3b5 Saf 3.0 Win Saf 3.1 Win Opera 9.26 Opera 9.5b Konqueror 3.5.7
applyElement()
Something with nodes

Test page
Yes No No No No
var y = document.createElement('i');
x.applyElement(y)

The <i> element is inserted into element x, around the text.

clearAttributes()
Remove all attributes from a node

Test page
Incomplete No No No No
x.clearAttributes()

Remove all attributes from node x.

  • IE doesn't clear event handlers. IE 7 doesn't clear inline styles.
mergeAttributes()
Copy all attributes of one node to another node

Test page
Yes Incomplete No No No No
x.mergeAttributes(y)

Copy all of node y's attributes to node x.

  • IE8b1 doesn't copy the style attribute.
removeNode()
Remove a node

Test page
Yes No No Yes No
x.removeNode(true | false)

Remove node x from the document. If you use the argument true its children are also removed; if you use false they aren't. Note that all text nodes count as children, too.

replaceNode()
Replace a node by another node

Test page
Yes No No No No
x.replaceNode(y)

Replace node x by node y.

swapNode()
Swap two nodes

Test page
Yes No No No No
x.swapNode(y)

Put node x in node y's place and vice versa.

Method or property IE 5.5 IE 6 IE 7 IE8b1 FF 2 FF 3b5 Saf 3.0 Win Saf 3.1 Win Opera 9.26 Opera 9.5b Konqueror 3.5.7