Attr (W3C DOM Core object)
| Version | Depr. | Parent |
|---|---|---|
| DOM1 | No | Node |
| IE5.5+ | FF1.5+ | SA3+ | OP9+ |
|---|---|---|---|
| Buggy | Buggy | Full | Buggy |
Example
<link rel="stylesheet" type="text/css" href="default.css" />
The example above contains three attribute nodes: a
rel attribute with the value
stylesheet, a type attribute
with the value text/css, and an
href attribute with the value
default.css.
Description
The Attr
interface inherits from Node and represents a single
attribute of an Element node.
However the Attr interface is a special case
in terms of inheritance — attribute nodes are not child nodes of the
element they belong to, and have no parent or sibling nodes, so although
inherited Node
properties such as parentNode and
nextSibling
are available, they always return null. Attributes are
considered by the DOM to be properties of elements, rather than objects in
their own right.
This is intended by the standard to make it easier to implement the DOM as an API layer on top of existing, legacy object models. And this is exactly what we see with HTML, in the way that known attributes are generally available as dot-properties of the element object they belong to.
However this intention, while good, is also a major reason why attribute implementations are such a mess across browsers!
An attribute may have an explicit or implicit value. An
explicit value is one that's actually set by the
author. An implicit value is where no explicit
value is set but the document type has a default for that attribute; the
default might be a specific value (such as the type
attribute of an <input>, which defaults to
text), or it might be empty (every HTML element has a
default id and class
attribute with an empty string as its value; in a DTD this corresponds
with the #IMPLIED token).
However, empty default attributes do not appear in the DOM tree — only those attributes which have an actual value (either a specific default value in the DTD, or an explicit value) appear in the DOM; this is referred to as having an effective value.
The value can be both
retrieved and set using the value property of
the Attr node, or the nodeValue
property of Node, or
using methods of the owning Element such as getAttribute and setAttribute. An Attr node
itself can be retrieved with getAttributeNode
and added with setAttributeNode. When setting
a value, the value is not parsed, so any entity references or other markup
will be treated as literal text. To create an attribute containing
entities the specification suggests to create an Attr
node with appropriate Text and EntityReference
nodes as children, then add it to an element using setAttributeNode, however in practise this rarely
works (see the Compatibility notes below for details).
Similarly,
the content of an Attr node may be considered child
nodes, or it may be considered a simple string, and this varies by
implementation (see the Compatibility notes below for details). Either
way, the value and nodeValue
properties return a string representation of this content.
The range of values a particular attribute is allowed to have is usually defined in the DTD.
Attribute types in Internet Explorer
In
Internet Explorer in HTML, attributes retrieved using getAttribute are not actually mapped to element
attributes at all, they're mapped to DOM properties. This has several
significant (and annoying) implications:
- Values are not all returned as strings: a
styleattribute returns astyleobject, an event-handling attribute such asonclickreturns the contents of the event handler wrapped in an anonymous function, an attribute which evaluates to a boolean (such asdisabledorchecked) returns a boolean, and an attribute which evaluates to a number (such astabindex) returns a number. - Some attributes can only be retrieved using the camel-cased name
they use for their DOM property equivalent. The most notable examples
are
className(forclass) andhtmlFor(forfor); other examples aretabIndexandaccessKey. - The
hrefof an<a>element and thesrcof an<img>element are both returned as fully-qualified URIs instead of the literal attribute value.
See getAttribute for a thorough
rundown!
Namespaces on attributes
Unlike Element nodes, Attr nodes do not inherit a
namespace from the element they're attached to — if an attribute does not
have an explicitly defined namespace then it simply has no
namespace.
The DOM consider that It would be redundant to require the use of a namespace prefix on every attribute that belongs to a specific element, so rather than this:
<html:a html:href="…">
We can simply put this:
<html:a href="…">
The
href attribute is effectively a property of the
<a> element - it has no namespace of its own, but
it doesn't need one because it belongs to an element that does. The
side-effect of this is that a namespaced attribute method such as getAttributeNS won't retrieve that attribute using
the namespace of its owning element. The following example will not match
the attribute above, because it isn't in the XHTML namespace, it's in no
namespace:
element.getAttributeNS('http://www.w3.org/1999/xhtml',
'href');
If we set an attribute called
html:href on that same element, then we will in
fact have created a second attribute — even though it has the same local
name as the href attribute, it has a different
namespace, hence it's a different attribute according to the
DOM:
element.setAttributeNS('http://www.w3.org/1999/xhtml',
'html:href', '/home/');
Having said that, some
implementations will consider it to be the same attribute in some
circumstances (see setAttributeNS for
details). Such consideration cannot be really be called a bug, because the
DOM does not define attribute associations (that job is handled by a DTD);
it's more like a convenience feature, though admittedly a very confusing
one!
The more simple case of attribute namespacing is where an
attribute has an explicit prefix. This example will match an attribute
called xml:lang in the XML namespace:
element.getAttributeNS('http://www.w3.org/XML/1998/namespace',
'lang');
Compatibility
| Internet Explorer | Firefox | Safari | Opera | |||||||
|---|---|---|---|---|---|---|---|---|---|---|
| 5.5 | 6.0 | 7.0 | 1.5 | 2.0 | 3.0 | 1.3 | 2.0 | 3.0 | 9.0 | 9.5 |
| Buggy | Buggy | Buggy | Buggy | Buggy | Buggy | Buggy | Buggy | Full | Buggy | Buggy |
In
Internet Explorer empty default attributes
do appear in the DOM, and can be retrieved from the attributes collection.
Internet
Explorer 5.5 in HTML cannot retrieve attribute nodes, only
attribute values, which means that the majority of this interface is
untestable in that browser. However attribute values retrieved through the
attributes collection do expose the specified
property, and inherit the nodeName and
nodeValue
properties of Node.
Internet Explorer 6 and 7 don't
implement the ownerElement
property; and don't inherit the normalize method
from Node. These
browsers also have a myriad of bugs and quirks relating to the retrieval,
setting and changing of attribute values, most of which are down to the
way that attributes are mapped to DOM properties (as noted above). More
details can be found in the documentation for each attribute method
individually (such as getAttribute).
Internet Explorer in HTML,
Firefox and Opera do
not support the creation of attribute values by appending Text or EntityReference
nodes to an Attr node, they only support setting the
value or
nodeValue
property.
Internet Explorer in HTML,
Safari 1.3 and 2 and
Opera do not consider the value of an
attribute to be a child Text node of the
Attr node: in Internet Explorer in
HTML childNodes
is null; in Safari 1.3 and
2 and Opera it's a collection
with zero members. However the specification contradicts itself on
which is the correct behavior1, therefore neither behavior is
considered a bug.
In Internet Explorer in HTML
and Firefox the specified
property of an attribute that's been created but not yet added to an
element returns false (should be
true).
In Safari 1.3 and
2 the value property of
an attribute node is readonly (i.e. it can't be used to set the value,
only retrieve it).
In Opera 9.0 in HTML
mode2 the name of an attribute
is often returned in uppercase; a consistent pattern for when this
does/doesn't occur could not be established, but appears to be related to
whether that attribute has already been referred to in lower case (in
which case its name is returned in lowercase, otherwise uppercase). Also
Opera 9.0 in pure XML (but not XHTML
mode3) parses entities when setting the value of an attribute (via any of
the attribute methods, or the attributes
collection), contrary to the specification.
In this Section
name
The name of anAttrnode.ownerElement
TheElementnode this attribute is attached to.specified
Whether this attribute has an explicit value, or has been manipulated such that itsownerElementisnull.value
The value of an Attr node.
Footnotes
1 In the Attr interface
specification it says that "In XML, where the value of an
attribute can contain entity references, the child nodes of the Attr
node may be either Text or EntityReference nodes...", which implies
that attribute values are considered child nodes only in XML, but
could also be interpreted to mean that attribute values can only
contain entities in XML. However it then goes on to say that
"Because the DOM Core is not aware of attribute types, it treats all
attribute values as simple strings...", implying that an attribute
never has child nodes. Later, in the Element interface
specification it says "In XML, where an attribute value may
contain entity references, an Attr object should be retrieved to
examine the possibly fairly complex sub-tree representing the
attribute value. On the other hand, in HTML, where all attributes have
simple string values..."; this re-inforces the original inference
that attribute values are considered child nodes only in XML. However
in the setAttribute
specification it says that "to assign an attribute value that
contains entity references, the user must create an
Attr node plus any Text and
EntityReference nodes, build the appropriate
sub-tree, and use setAttributeNode to assign it
as the value of the attribute...", without mentioning any caveat
for document types. The overall inference is that attribute values in
HTML are always simple strings, and attribute values in XML may be
simple strings or child nodes, however the specification is not
sufficiently clear on this point to be able to say absolutely that one
or the other is correct.
2 On XHTML or HTML pages served as
text/html.
3 On XHTML pages served as application/xhtml+xml.
User-contributed notes
There are no comments yet.
Add a note
To post a note on this topic, please log in with your SitePoint username and password. If you don't have an account yet, you can create a new account for free.