Приглашаем посетить
Майков (maykov.lit-info.ru)

Parsing Information

Parsing Information

Every element exposes information about itself and its relationship to other elements. The exposed information falls into two categories: parsing information and rendering information. The parsing information relates directly to the attributes, styles, and contents defined by the document. The rendering information represents the information calculated by the browser before displaying the element.

The parsing information includes the identifying properties discussed earlier, all the specified known and unknown HTML attributes, the inline style sheet, and the element's relationship to other elements as defined by the document. The inline style sheet is parsing information, not rendering information, because it is defined explicitly in the document's source, rather than calculated at render time.

The rendering information is information that is calculated by the browser during the composition of the document. Rendering information includes the position and size of the element in relation to its rendering context—that is, who drew the element, which rendering context the element belongs to, and the positions of any scrollbars. Rendering contexts and the resulting rendering tree are discussed in detail in Chapter 12, "Dynamic Positioning." The remainder of this section focuses on accessing and using the parsing tree.

Determining HTML Containership

A couple of techniques are available for determining what elements are contained within other elements. As mentioned, the parent element of an element can be determined using the parentElement property. The child elements contained within an element are enumerated by a children collection and an all collection on the element. The children collection represents the immediate child elements, while the all collection represents all the contained elements.

Accessing Child Elements

The all collection on the document represents all the HTML elements contained by the document. This containership concept is carried through to every element object. Every element object also exposes an all collection that represents all the elements contained within that element. In addition, a children collection is exposed representing the elements that are immediate children of the current element. These collections work in the same manner as the document element collections introduced in Chapter 7, "Document Element Collections." Using these collections, you can create a highly customized collection. Here are a few examples:

// All the H1 elements that are children of the body
document.body.children.tags("H1") 
// All LI elements in the third UL element on the page
document.all.tags("UL")[2].children.tags("LI")
// All Paragraph elements contained anywhere within the first DIV
// element, even in a nested DIV or Table element
document.all.tags("DIV")[0].all.tags("P")

Determining Whether One Element Is Contained Within Another

As mentioned in Chapter 3, "Dynamic HTML Event Model," every element exposes a contains method that can be used to quickly determine whether another element is within its scope. The contains method takes an element and returns a value of true if the element is a child element, a child of a child, and so forth.

The contains method was introduced to simplify writing onmouseover and onmouseout event handlers. Code in Chapter 3, "Dynamic HTML Event Model," demonstrates how to use the contains method to check whether the mouse cursor has entered or exited the element on which the event fired and hasn't only entered or exited a child element.

The sourceIndex Property

All elements expose a read-only 32-bit integer sourceIndex property that contains the element's ordinal position in the document's all collection. This position is also the position of the element in the parsing tree if the tree were flattened into a list. The sourceIndex property can be used to determine the relative location of an element and its relationship to other elements in the document.

Do not rely on the sourceIndex property to return the same value; the indexing can change if more elements are created for the document in the future. For example, do not expect two elements' sourceIndex values to always be a fixed distance apart. If you use the sourceIndex property, make comparisons by generically locating an element in a loop.

Constructing a Parsing Tree

One of the best ways to understand the containment relationships in an HTML document is to construct the parsing tree using the document's all collection. The following document contains code that automatically outputs a nested table representing the containership hierarchy of each element in the document. This code fragment can be placed in any document to get a quick tree view.

<HTML>
   <HEAD>
      <TITLE>Tree Builder</TITLE>
      <SCRIPT LANGUAGE="JavaScript">
         function buildTree() {
            var intParents = 0;
            var intIndent = 0;
            // strStruct stores the HTML string that
            // will represent the document.
            var strStruct = "<HTML><TITLE>Document Tree</TITLE>" +
               "<BODY><TABLE BORDER CELLPADDING=5><TR>";
            var elParent;
            // Walk through every element in the document.
            for (var intLoop = 0; intLoop < document.all.length;
                  intLoop++) {
               elParent = document.all[intLoop];
               // Determine depth of the element.
               while (elParent.tagName != "HTML") {
                  intParents++;
                  elParent = elParent.parentElement;
               }
               // Nest or close nesting based on new depth.
               if (intParents > intIndent)
                  strStruct +=
                     "<TABLE BORDER WIDTH=100% CELLPADDING=5><TR>";
               else if (intParents < intIndent) { 
                  for (var intClose = intParents;
                        intClose < intIndent; intClose++)
                     strStruct += "</TABLE>";
               }
               intIndent = intParents;
               intParents = 0;
               strStruct += "<TD>" +
                  document.all[intLoop].tagName;
            }
            // Close any remaining scopes.
            for (var intClose = intParents; intClose < intIndent;
                  intClose++)
               strStruct += "</TD></TR></TABLE>";
            strStruct += "</BODY></HTML>";
               // Output the new document in a new window.
            var w = window.open("", "tree");
            w.document.open();
            w.document.write(strStruct);
            w.document.close();
         }
         window.onload = buildTree;
      </SCRIPT>
   </HEAD>
   <BODY>
      <H1>Tree Builder</H1>
      <UL>
         <LI>Test Item 1
            <UL>
               <LI>Subitem 1
               <LI>Subitem 2
            </UL>
         </LI>
         <LI>Test Item 2</LI>
      </UL>
      <DIV>
         <P>This is <EM>cool.</EM></P>
      </DIV>
   </BODY>
</HTML>

This code constructs the tree by enumerating the document's all collection and calculating the depth of each element using the parentElement property. This routine could be rewritten recursively using the children collection on each element.

Figure 8-1 shows the containership hierarchy generated by this code. The nested tables show what elements are scoped within what other elements.

Parsing Information

Figure 8-1. The containership hierarchy for an HTML document.

The document Property

Each element exposes a document property that represents the document the element belongs to. This property allows generic scripts to determine what document—and from the document, what window—an arbitrary element originated from. For example, the following expression references the window containing the element:

myElement.document.parentWindow  // The window for an element.

[Содержание]