As in external files of HTML, the organization of markup is separate from its style, format, and behavior. While you can certainly change the style of elements or text with JavaScript, it's more interesting to actually change the organization of how your markup is laid out.
Just remember that your markup only provides organization, a framework, and you'll be on your way to success. Take a small step further and you'll see how the browser takes all that text organization and turns it into something super interesting, a set of objects, each of which can be changed, added, or removed.
Advantages of Text Markup
Before discussing Web browsers, it's worth considering why plain text is the absolute best choice for storing HTML (see some other ideas about markup for more information). Regardless of the pros and cons, just recall that HTML is sent over the network to the Web browser every time a page is viewed (for brevity, caches, etc. are not taken into account). There really is no more efficient way to deliver text. Binary objects, graphical representations of pages, reorganized markup blocks, and so on, all of which are more difficult to pass over the network than plain text files.
In addition, the browser also adds to the glory. Today's browsers allow users to change text size, scale images, download the page's CSS or JavaScript (in most cases), and more, which completely precludes sending any kind of graphical representation of the page to the browser. However, the browser needs the raw HTML so that it can apply any processing to the page in the browser, rather than trusting the browser to handle that task. Likewise, separating CSS from JavaScript and CSS from HTML markup require a format that can be easily separated. Once again, text files are the best method for this task.
Last but not least, remember that new standards (such as HTML 4.01 and XHTML 1.0 and 1.1) promise to separate content (the data in the page) from presentation and style (usually applied by CSS). If programmers were to separate HTML from CSS and then force the browser to retrieve some representation of the page that glues the various parts of the page together, they would lose most of the benefits of these standards. Keeping these parts separate when they arrive at the browser gives the browser unprecedented flexibility in getting HTML from the server.
Additional Thoughts on Markup
Plain Text Editing: Right or Wrong?
Plain text is ideal for storing markup, but not suitable for editing markup. Popular is the use of IDEs, such as Macromedia DreamWeaver or the more powerful Microsoft® FrontPage®, to manipulate Web page markup. These environments often provide shortcuts and help for creating Web pages, especially when using CSS and JavaScript, both of which come from files other than the actual page markup. It doesn't matter that many people still prefer good old Notepad or vi (I admit I'm one of them). Either way, the end result is a text file full of markup.
Text on the Web: The good stuff
has been said, text is the best medium for documents, like HTML or CSS, being transmitted thousands of times over the Web. When I say it's difficult for a browser to represent text, I'm specifically referring to converting text into a visual graphical page for the user to view. This has nothing to do with how the browser actually retrieves the page from the Web browser; in this case, text is still the best choice.
Disadvantages of Text Markup
Just as text markup has surprising advantages for designers and page creators, it also has quite surprising disadvantages for browsers. Specifically, it's difficult for browsers to directly represent text markup visually to the user (see some other ideas about markup for details). Consider the following common browser tasks:
·Apply CSS styles (usually from multiple style sheets in external files) to markup based on the element type, class, ID, and its position in the HTML document.
·Apply styles and formatting to different parts of the HTML document based on JavaScript code (usually located in an external file).
·Change form field values based on JavaScript code.
·Based on JavaScript code, supports visual effects such as image flipping and image swapping.
The complexity doesn't lie in coding these tasks; everything in them is fairly easy. The complexity comes from the browser actually implementing the requested action. If the markup is stored as text, for example, if you want to enter text (text-align: center) in the p element of the center-text class, how to achieve this?
·Add inline styles to text?
·Apply styles to HTML text in the browser and just keep the content centered or not?
·Apply unstyled HTML and then apply formatting afterwards?
These very difficult problems are why so few people write browsers today. (Whoever wrote the browser should accept my sincerest thanks.)
There is no doubt that plain text is not a good way to store the browser's HTML, although text is the best solution for getting the page markup. Throw in JavaScript's ability to change the structure of the page, and things get a little more nuanced. Should the browser rewrite the modified structure to disk? How can you keep the latest version of the document?
Certainly, text is not the answer. It's difficult to modify, it's difficult to apply styles and behaviors to it, and it's fundamentally far removed from the dynamic nature of today's Web pages.
The answer to the problem ofresorting to tree views
(at least the answer chosen by today's Web browsers) is to use a tree structure to represent HTML. See Listing 1, a fairly simple and boring HTML page that represents the markup for this article.
Listing 1. Simple HTML page<html>
in text markup
<head>
<title>Trees, trees, everywhere</title>
</head>
<body>
<h1>Trees, trees, everywhere</h1>
<p>Welcome to a <em>really</em> boring page.</p>
<div>
Come again soon.
<img src="come-again.gif" />
</div>
</body>
</html>
The browser accepts the page and converts it into a tree structure, as shown in Figure 1.
To keep this article moving, I've simplified it a bit. Experts in DOM or XML will be aware of the impact whitespace has on the way a document's text is represented and broken down in a Web browser's tree structure. A superficial understanding only makes things ambiguous, so if you want to figure out the impact of white space, that's your best bet; if not, just keep reading and don't think about it. When it becomes a problem, that's when you'll know everything you need.
Aside from the actual tree background, the first thing you might notice is that everything in the tree starts with the outermost HTML containing element, the html element. Using the metaphor of a tree, this is called the root element. So even though this is the bottom level of the tree, when you look at and analyze the tree, I usually start with this. If it does work, you could turn the whole tree upside down, but that does stretch the tree metaphor a bit.
The lines flowing from the root represent the relationship between the different labeled parts. The head and body elements are children of the html root element; title is a child of head, and the text "Trees, trees, everywhere" is a child of title. The entire tree is organized in this way until the browser obtains a structure similar to Figure 1.
Some additional terminology
To keep with the tree metaphor, the head and body are called branches of html. They are called branches because they have children of their own. When you reach the end of the tree, you'll get to the main text, like "Trees, trees, everywhere" and "really"; these are often called leaves because they don't have children of their own. You don't need to remember all of these terms, it's much easier to just imagine the tree structure when you're trying to figure out what a particular term means.
Object Values
Now that you understand some basic terminology, it's time to focus on the small rectangle that contains the element name and text (Figure 1). Each rectangle is an object; the browser resolves some text issues within it. By using objects to represent each part of an HTML document, you can easily change the organization, apply styles, allow JavaScript to access the document, and more.
Object Types and Property
Markers Each possible type has its own object type. For example, elements in HTML are represented by the Element object type. The text in the document is represented by the Text type, the attributes are represented by the Attribute type, and so on.
So not only can Web browsers use an object model to represent documents (thus avoiding having to deal with static text), but they can also use object types to immediately tell what something is. The HTML document is parsed and converted into a collection of objects, as shown in Figure 1, and things like angle brackets and escape sequences (for example, use < for < and > for >) are no longer an issue. This makes the browser's job (at least after parsing the input HTML) much easier. It's easy to figure out whether something is an element or an attribute and determine how to handle objects of that type.
By using objects, a Web browser can change the properties of these objects. For example, each element object has a parent element and a list of child elements. So adding a new child element or text simply adds a new child element to the element's list of child elements. These objects also have a style property, so quickly changing the style of an element or text segment is very simple. For example, to use JavaScript to change the height of a div, look like this:
someDiv.style.height = "300px";
In other words, a web browser makes it very easy to change the appearance and structure of a tree using object properties. Compare this to the complicated things a browser has to do internally to represent a page as text, every change to a property or structure requires the browser to rewrite the static file, reparse it, and redisplay it on the screen. With objects, all this is solved.
Now, take a moment to expand some HTML documents and outline them with a tree. Although this may seem like an unusual request (especially in an article like this that contains so little code), if you hope to be able to manipulate these trees, you need to be familiar with their structure.
Along the way, you might discover some weird things. For example, consider the following:
What happens to the attribute?
·What about text broken into elements (such as em and b)?
·What about HTML that is not properly structured (for example, when the closing p tag is missing)?
Once you are familiar with these issues, you will be able to better understand the following sections.
Strictness Is Sometimes a Good Thing
If you try Exercise I just mentioned, you may find some potential issues with the marked tree view (if not, just take my word for it!). In fact, some problems will be found in Listing 1 and Figure 1. First, look at how the p element is decomposed. If you ask the average Web developer "What is the text content of the p element?" the most common answer will be "Welcome to a really boring Web page." If you compare this with Figure 1, you will see that this answer (although logical) is simply not correct.
In fact, the p element has three different child objects, none of which contain the complete "Welcome to a really boring Web page." text. You'll find parts of the text like "Welcome to a " and "boring Web page," but not all of it. To understand this, remember that anything in the markup must be converted to an object of some type.
Also, the order doesn't matter! Can you imagine how a user would respond to a Web browser if the browser displayed the correct objects, but in a different order than you provided them in the HTML? What if the paragraph is sandwiched between the page title and the article title, and that's not how you organize your document yourself? Obviously, the browser must maintain the order of elements and text.
In this example, the p element has three different parts:
· The text before the em element · The em element itself · The text after the em element
If you mess up this order, you might focus on the wrong part of the text. To keep everything in order, the p element has three child objects, in the order shown in Listing 1's HTML. Moreover, the key text "really" is not a child element of p; it is a child element of em, a child element of p.
It is very important to understand this concept. Although "really" text will likely appear with other p element text, it is still a direct child of the em element. It can have a different format than other p text, and can be moved around independently of other text.
To keep this in mind, try diagramming the HTML in Listings 2 and 3 to ensure that the text has the correct parent element (regardless of how the text will ultimately appear on the screen).
Listing 2. Markup
<html>
with clever element nesting
<head>
<title>This is a little tricky</title>
</head>
<body>
<h1>Pay <u>close</u> attention, OK?</h1>
<div>
<p>This p really isn't <em>necessary</em>, but it makes the
<span id="bold-text">structure <i>and</i> the organization</span>
of the page easier to keep up with.</p>
</div>
</body>
</html>
Listing 3. More clever element nesting
<html>
<head>
<title>Trickier nesting, still</title>
</head>
<body>
<div id="main-body">
<div id="contents">
<table>
<tr><th>Steps</th><th>Process</th></tr>
<tr><td>1</td><td>Figure out the <em>root element</em>.</td></tr>
<tr><td>2</td><td>Deal with the <span id="code">head</span> first,
as it's usually easy.</td></tr>
<tr><td>3</td><td>Work through the <span id="code">body</span>.
Just <em>take your time</em>.</td></tr>
</table>
</div>
<div id="closing">
This link is <em>not</em> active, but if it were, the answers
to this <a href="answers.html"><img src="exercise.gif" /></a> would
be there. But <em>do the exercise anyway!</em>
</div>
</div>
</body>
</html>
You will find the answers to these exercises in the GIF files at the end of this article, tricky-solution.gif in Figure 2 and trickier-solution.gif in Figure 3. Don't peek, take the time to answer it automatically first. This will help you understand how strict the rules apply when organizing the tree, and will really help you master HTML and its tree structure.
What about attributes?
Are you running into some problems when trying to figure out what to do with properties? As mentioned before, the attribute does have its own object type, but the attribute is indeed not a child of the element that displays it. The nested element and the text are not at the same attribute "level", as you will notice, the answers to the exercises in Listings 2 and 3 No properties are shown.
Properties are actually stored in the object model used by browsers, but they have some special cases. Each element has a list of available properties, separate from the list of child objects. So a div element might have a list containing an attribute "id" and another attribute "class".
Remember that element attributes must have unique names, that is, an element cannot have two "id" or two "class" attributes. This makes the list easy to maintain and access. As you'll see in the next article, you can simply call a method such as getAttribute("id") to get the value of an attribute by name. Similar method calls can also be used to add properties or set (reset) the value of existing properties.
It is worth pointing out that the uniqueness of the attribute names makes this list different from the list of sub-objects. A p element can have multiple em elements, so the child object list can contain multiple duplicates. Although child lists and property lists operate similarly, one can contain duplicates (children of an object) while one cannot (properties of an element object). Finally, only elements have attributes, so text objects don't have an additional list for storing attributes.
Messy HTML
Before moving on to how browsers convert markup into a tree representation, there is another topic worth exploring, namely how browsers handle markup that is not well-formed. Well-formed is a term widely used in XML and has two basic meanings:
·Every opening tag has a matching closing tag. So every <p> in the document matches </p>, every <div> matches </div>, and so on.
The innermost start tag matches the innermost end tag, then the next innermost start tag matches the next innermost end tag, and so on. So <b><i>bold and italics</b></i> is illegal because the innermost opening tag <i> does not match the innermost closing tag <b> properly. To make it well-formed, either switch the opening tag order or the closing tag order. (If you switch both, the problem will still occur).
Take a closer look at these two rules. These two rules not only simplify document organization but also eliminate uncertainty. Should bold be applied first and then italic? Or just the opposite? If this ordering and uncertainty doesn't seem like a big deal, keep in mind that CSS allows rules to override other rules, so, for example, if the text in the b element has a different font than the font in the i element, the order in which the formatting is applied will change. It's very important. Therefore, the well-formedness of HTML plays a crucial role.
If the browser receives a document that is not well-formed, it will do its best. The resulting tree structure will be, at best, an approximation of the original page that the author intended, and at worst, be unrecognizable. If you've ever loaded a page into your browser and seen completely unexpected results, you probably looked at the browser results and guessed how your structure should be, and continued working in frustration. Of course, fixing this problem is pretty simple: make sure the document is well-formatted! If you're not sure how to write standardized HTML, consult your resources for help.
Introduction to the DOM
By now, you know that browsers convert Web pages into object representations, and you may have even guessed that object representations are DOM trees. DOM stands for Document Object Model and is a specification available from the World Wide Web Consortium (W3C) (you can see some DOM-related links in Resources).
But more importantly, the DOM defines the types and properties of objects, allowing the browser to represent markup. (The next article in this series will be devoted to the specifications for using the DOM in JavaScript and Ajax code.)
Document Object
First, you need to access the object model itself. It's very easy; to use the built-in document variable in any JavaScript code that runs on a Web page, you can write code like this:
var domTree = document;
Of course, this code itself is useless, but it demonstrates that every Web browser makes document Objects can be used in JavaScript code, and a complete tree of object representation markup is demonstrated (Figure 1).
Each item is a node
. Obviously, the document object is important, but that's just the beginning. Before going any further, there's another term to learn: nodes. You already know that every part of markup is represented by an object, but it's not just any object, it's a specific type of object, a DOM node. More specific types, such as text, elements, and attributes, all inherit from this basic node type. So there can be text nodes, element nodes and attribute nodes.
If you already have a lot of JavaScript programming experience, you're probably already working with DOM code. If you've been following this Ajax series so far, you must have been working with DOM code for a while now. For example, the line of code var number = document.getElementById("phone").value; uses the DOM to find a specific element and then retrieves that element's value (in this case, a form field). So even if you don't realize it, you are using the DOM every time you type a document into JavaScript code.
To elaborate on the terms you have already learned, a DOM tree is a tree of objects, but more specifically, it is a tree of node objects. In Ajax applications or any other JavaScript, you can use these nodes to produce effects such as removing elements and their contents, highlighting specific text, or adding new image elements. Because they all occur on the client side (the code running in the Web browser), these effects occur immediately without communicating with the server. The end result is often that the application feels more responsive because content changes on the Web page without long pauses while the request is directed to the server and the response is interpreted.
In most programming languages, you need to learn the actual object name of each node type, learn the available properties, and figure out types and casts; but in JavaScript this is not necessary. You can just create a variable and assign it the object you wish (as you've already seen):
var domTree = document;
var phoneNumberElement = document.getElementById("phone");
var phoneNumber = phoneNumberElement.value;
There is no type, JavaScript creates the variable as needed and assigns it the correct type. As a result, working with the DOM from JavaScript becomes trivial (a future article will be dedicated to the DOM in relation to XML, which will be even more ingenious).
Inclosing
, I want to leave you with a bit of suspense here. Obviously, this is not a completely exhaustive description of the DOM; in fact, this article is just an introduction to the DOM. There is much more to the DOM than what I have introduced today!
The next article in this series will expand on these ideas and dive into how to use the DOM in JavaScript to update Web pages, quickly change HTML, and create a more interactive experience for your users. I'll return to the DOM again in a later article dedicated to using XML in Ajax requests. So be familiar with the DOM, which is a major part of Ajax applications.
At this point, understanding the DOM in depth would be quite simple, like detailing how to move around the DOM tree, get the values of elements and text, iterate through lists of nodes, etc., but this might leave you with the impression that the DOM is all about code , which is not the case.
Before reading the next article, try thinking about a tree structure and try it out with some HTML of your own to see how a Web browser converts HTML into a tree view of markup. Additionally, think about the organization of the DOM tree and practice it with the special cases introduced in this article: attributes, text with elements mixed in, and elements with no text content (such as the img element).
Having a solid grasp of these concepts and then learning the syntax of JavaScript and the DOM (next article) will make responding much easier.
And don't forget, there are answers to Listings 2 and 3, complete with sample code!