PPK on JavaScript: The DOM - Part 2/Page 7 | WebReference

PPK on JavaScript: The DOM - Part 2/Page 7


[previous] [next]

PPK on JavaScript: The DOM - Part 2

G: Attributes

Attributes are a bit odd. Although officially they're nodes, they are not fully-fledged parts of the document tree and do not appear in, for instance, the childNodes[] list of their parent node. Furthermore, many common HTML attributes, like the src of an <img> or the href of an <a>, are also JavaScript properties, which means you don't need the W3C DOM attribute methods to read or change them. Finally, the handling of attributes is the area of the W3C DOM that contains most browser incompatibilities, and only about 20% of this part of the specification actually works correctly in all browsers.

Attributes are always name/value pairs. Take a well-known attribute:

The name of the attribute is src, and its value is "pix/theImage.gif". Unsurprisingly, all attributes have a name and a value property that give the name and value of the attribute.

Attributes, Properties, and Browser Compatibility: I do not treat any W3C DOM attribute method or property except for getAttribute() and setAttribute(), because most of them are subject to one browser bug or a nother (and therefore useless). You can study the W3C DOM browser-compatibility tables at www.quirksmode.org.

Getting and setting attributes

The W3C DOM has two more or less reliable attribute methods: getAttribute() and setAttribute(). The first one is used often, the second rather less.

getAttribute() requires an attribute name and returns the value of that attribute. setAttribute() requires an attribute name and value, and sets that attribute to the new value. Take this example:

You access the <img> and ask for its src attribute. The browser returns the value of this attribute, and therefore the alert says 'https://www.quirksmode. org/pix/logo.gif'. Then you set the src attribute to a new value, and the image changes.

If an attribute does not exist, getAttribute() returns null.

Custom attributes

getAttribute() and setAttribute() work on any attribute an HTML tag contains, even custom ones, i.e., attributes that are not officially a part of any (X)HTML specification. I take advantage of this fact in Textarea Maxlength, Usable Forms, and Form Validation. All three scripts require the HTML coder to use custom attributes to give the script instructions. We already discussed the use and dangers of custom attributes in Section 4B. In this chapter it's enough to say that any HTML attribute is available through getAttribute().

Limitations

WARNING Browser incompatibilities ahead

Unfortunately, these methods have a few problems in Explorer 6 and earlier. Many HTML tags have special attributes to store their inline styles (style) and their event handlers (onclick, onkeydown, etc.). In Explorer, these attributes cannot be read or set through getAttribute() and setAttribute(); in fact, weird bugs may occur if you try it.

The solution is to use the JavaScript properties style, onclick, onkeydown, etc. to read or set these attributes. In order to completely understand this, we first have to discuss the subtle difference between HTML attributes and JavaScript properties.

HTML attributes and JavaScript properties

Although superficially they might seem the same, and there is in fact considerable overlap, HTML attributes are not always equal to JavaScript properties.

Let's dissect a few lines from Sandwich Picker. Each

in the document contain one sandwich. I need to know the price of this sandwich to calculate the total price when the user orders it. Because the purpose of the script is to change the placement of these <tr>s in the document, I want to attach the price of a sandwich to its <tr>. In that way, the price always remains easily available, wherever the <tr> may happen to be at a certain time.

Figure 8.16



Figure 8.16: All sandwiches below this header are priced at 2.00.

Sandwich prices are located in the header <tr>s of the third table. I put them in a custom attribute in the HTML. Note that this is an HTML attribute; it's hard-coded in the page's HTML.

Browser Incompatibilities: Some browsers (Explorer and Safari at the time of writing) equate HTML attributes and JavaScript properties, and allow you to use x[i].price and x[i].getAttribute('price') indiscriminately.

Other browsers see HTML attributes and JavaScript properties as different things. To keep your scripts cross-browser compatible, it's best to treat attributes and properties as distinct entities.

When the script encounters the price attribute, it sets this price to all following sandwiches, until it encounters a new price attribute.

The first two lines read the HTML custom attribute price and then set currentPrice to its value. The third line sets the JavaScript price property of the <tr> to the value of currentPrice.

Even though they share a name, the HTML custom attribute and the JavaScript property are different things. The HTML attribute is located in the document tree as an attribute node of the <tr>, while the JavaScript property belongs to the object that represents the <tr> and is not present in the document tree. This is the general rule. There are, however, numerous exceptions.

Attribute/property mappings

Before W3C specified the DOM, JavaScript needed a way to access a few important HTML attributes, like the value of a form field or the src of an image. In order to do this without the as-yet-unspecified getAttribute() method, JavaScript's inventors decided to map certain properties of JavaScript objects to HTML attributes.

For instance, all image objects would have a JavaScript src property that was equal to the HTML src attribute. Therefore these two lines are the same, though only the second one works in older browsers:

It's important to note that this is not a general rule, but that the browser vendors have hand-picked certain important attributes and created JavaScript properties to match them. These attribute/property mappings are most often found in the areas that have been open to scripting influences since the beginning: form fields, links, and images.

Later on, the style attribute that holds all inline styles of an element, as well as all event handlers (like onclick and onkeydown), were added to this list of special attributes/properties.

Although the W3C DOM now offers general and unrestricted access to all attributes, these special properties have never been removed from JavaScript, since that would mean that old scripts would stop working.

The best way of getting and setting attributes

With all this theoretical knowledge, we can discuss the best way of getting and setting attributes. I myself use these guidelines:

ppk on JavaScript

Excerpted from ppk on JavaScript by Peter-Paul Koch. Copyright © 2007. Used with permission of Pearson Education, Inc. and New Riders.

[previous] [next]

URL: