<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    posts - 73,  comments - 55,  trackbacks - 0
    < script?language = " JavaScript " >
    <!--
    var ?doc? = ? new ?ActiveXObject( " Msxml2.DOMDocument " );? // ie5.5+,CreateObject("Microsoft.XMLDOM")?


    // 加載文檔
    //
    doc.load("b.xml");

    // 創(chuàng)建文件頭
    var ?p? = ?doc.createProcessingInstruction( " xml " , " version='1.0'??encoding='gb2312' " );

    ????
    // 添加文件頭

    ????doc.appendChild(p);

    // 用于直接加載時獲得根接點

    //
    var?root?=?doc.documentElement;

    // 兩種方式創(chuàng)建根接點
    //
    ????var?root?=?doc.createElement("students");
    ???? var ?root? = ?doc.createNode( 1 , " students " , "" );

    ????
    // 創(chuàng)建子接點

    ???? var ?n? = ?doc.createNode( 1 , " ttyp " , "" );

    ????????
    // 指定子接點文本

    ???????? // n.text?=?"?this?is?a?test";
    ????
    ????
    // 創(chuàng)建孫接點

    ???? var ?o? = ?doc.createElement( " sex " );
    ????????o.text?
    = ? " " ;???? // 指定其文本


    ????
    // 創(chuàng)建屬性
    ???? var ?r? = ?doc.createAttribute( " id " );
    ????????r.value
    = " test "
    ;

    ????????
    // 添加屬性

    ????????n.setAttributeNode(r);

    ????
    // 創(chuàng)建第二個屬性????

    ???? var ?r1? = ?doc.createAttribute( " class " );
    ????????r1.value
    = " tt "
    ;
    ????????
    ????????
    // 添加屬性

    ????????n.setAttributeNode(r1);

    ????????
    // 刪除第二個屬性

    ????????n.removeAttribute( " class " );

    ????????
    // 添加孫接點

    ????????n.appendChild(o);

    ????????
    // 添加文本接點

    ????????n.appendChild(doc.createTextNode( " this?is?a?text?node. " ));

    ????????
    // 添加注釋

    ????????n.appendChild(doc.createComment( " this?is?a?comment\n " ));
    ????
    ????????
    // 添加子接點

    ????????root.appendChild(n);
    ????
    ????
    // 復(fù)制接點

    ???? var ?m? = ?n.cloneNode( true );

    ????????root.appendChild(m);
    ????????
    ????????
    // 刪除接點

    ????????root.removeChild(root.childNodes( 0 ));

    ????
    // 創(chuàng)建數(shù)據(jù)段

    ???? var ?c? = ?doc.createCDATASection( " this?is?a?cdata " );
    ????????c.text?
    = ? " hi,cdata "
    ;
    ????????
    // 添加數(shù)據(jù)段

    ????????root.appendChild(c);
    ????
    ????
    // 添加根接點

    ????doc.appendChild(root);

    ????
    // 查找接點

    ???? var ?a? = ?doc.getElementsByTagName( " ttyp " );
    ????
    // var?a?=?doc.selectNodes("http://ttyp");


    ????
    // 顯示改接點的屬性
    ???? for ( var ?i = ? 0 ;i < a.length;i ++ )
    ????
    {
    ????????alert(a[i].xml);
    ????????
    for ( var ?j = 0 ;j < a[i].attributes.length;j ++
    )
    ????????
    {
    ????????????alert(a[i].attributes[j].name);
    ????????}

    ????}


    ????
    // 修改節(jié)點,利用XPATH定位節(jié)點
    ???? var ?b? = ?doc.selectSingleNode( " //ttyp/sex " );
    ????b.text?
    = ? " "
    ;

    ????
    // alert(doc.xml);


    ????
    // XML保存(需要在服務(wù)端,客戶端用FSO)
    ???? // doc.save();
    ????
    ????
    // 查看根接點XML

    ???? if (n)
    ????
    {
    ????????alert(n.ownerDocument.xml);
    ????}


    // -->
    </ script >


    ??? 在
    DOM 眼中, HTML XML 一樣是一種樹形結(jié)構(gòu)的文檔, <html> 是根( root )節(jié)點, <head> 、 <title > 、 <body> <html> 的子( children )節(jié)點,互相之間是兄弟( sibling )節(jié)點; <body> 下面才是子節(jié)點 <table> <span> 、 <p> 等等。如下圖:
    HTML文檔結(jié)構(gòu).jpg
    ??? 這個是不是跟
    XML 的結(jié)構(gòu)有點相似呢。不同的是, HTML 文檔的樹形主要包含表示元素、標(biāo)記的節(jié)點和表示文本串的節(jié)點。


    ?HTML
    文檔的節(jié)點

    DOM 下, HTML 文檔各個節(jié)點被視為各種類型的 Node 對象。每個 Node 對象都有自己的屬性和方法,利用這些屬性和方法可以遍歷整個文檔樹。由于 HTML 文檔的復(fù)雜性, DOM 定義了 nodeType 來表示節(jié)點的類型。這里列出 Node 常用的幾種節(jié)點類型:

    接口

    nodeType 常量

    nodeType

    備注

    Element

    Node.ELEMENT_NODE

    1

    元素節(jié)點

    Text

    Node.TEXT_NODE

    3

    文本節(jié)點

    Document

    Node.DOCUMENT_NODE

    9

    document

    Comment

    Node.COMMENT_NODE

    8

    注釋的文本

    DocumentFragment

    Node.DOCUMENT_FRAGMENT_NODE

    11

    document 片斷

    Attr

    Node.ATTRIBUTE_NODE

    2

    節(jié)點屬性

    DOM 樹的根節(jié)點是個 Document 對象,該對象的 documentElement 屬性引用表示文檔根元素的 Element 對象(對于 HTML 文檔,這個就是 <html> 標(biāo)記)。 Javascript 操作 HTML 文檔的時候, document 即指向整個文檔, <body> <table> 等節(jié)點類型即為 Element 。 Comment 類型的節(jié)點則是指文檔的注釋。具體節(jié)點類型的含義,請參考《 Javascript 權(quán)威指南》,在此不贅述。

    Document 定義的方法大多數(shù)是生產(chǎn)型方法,主要用于創(chuàng)建可以插入文檔中的各種類型的節(jié)點。常用的 Document 方法有:

    方法

    描述

    createAttribute()

    用指定的名字創(chuàng)建新的 Attr 節(jié)點。

    createComment()

    用指定的字符串創(chuàng)建新的 Comment 節(jié)點。

    createElement()

    用指定的標(biāo)記名創(chuàng)建新的 Element 節(jié)點。

    createTextNode()

    用指定的文本創(chuàng)建新的 TextNode 節(jié)點。

    getElementById()

    返回文檔中具有指定 id 屬性的 Element 節(jié)點。

    getElementsByTagName()

    返回文檔中具有指定標(biāo)記名的所有 Element 節(jié)點。

    對于 Element 節(jié)點,可以通過調(diào)用 getAttribute() 、 setAttribute() 、 removeAttribute() 方法來查詢、設(shè)置或者刪除一個 Element 節(jié)點的性質(zhì),比如 <table> 標(biāo)記的 border 屬性。下面列出 Element 常用的屬性:

    屬性

    描述

    tagName

    元素的標(biāo)記名稱,比如 <p> 元素為 P HTML 文檔返回的 tabName 均為大寫。

    Element 常用的方法:

    方法

    描述

    getAttribute()

    以字符串形式返回指定屬性的值。

    getAttributeNode()

    Attr 節(jié)點的形式返回指定屬性的值。

    getElementsByTabName()

    返回一個 Node 數(shù)組,包含具有指定標(biāo)記名的所有 Element 節(jié)點的子孫節(jié)點,其順序為在文檔中出現(xiàn)的順序。

    hasAttribute()

    如果該元素具有指定名字的屬性,則返回 true 。

    removeAttribute()

    從元素中刪除指定的屬性。

    removeAttributeNode()

    從元素的屬性列表中刪除指定的 Attr 節(jié)點。

    setAttribute()

    把指定的屬性設(shè)置為指定的字符串值,如果該屬性不存在則添加一個新屬性。

    setAttributeNode()

    把指定的 Attr 節(jié)點添加到該元素的屬性列表中。

    Attr 對象代表文檔元素的屬性,有 name value 等屬性,可以通過 Node 接口的 attributes 屬性或者調(diào)用 Element 接口的 getAttributeNode() 方法來獲取。不過,在大多數(shù)情況下,使用 Element 元素屬性的最簡單方法是 getAttribute() setAttribute() 兩個方法,而不是 Attr 對象。


    使用
    DOM 操作 HTML 文檔

    Node 對象定義了一系列屬性和方法,來方便遍歷整個文檔。用 parentNode 屬性和 childNodes[] 數(shù)組可以在文檔樹中上下移動;通過遍歷 childNodes[] 數(shù)組或者使用 firstChild nextSibling 屬性進行循環(huán)操作,也可以使用 lastChild previousSibling 進行逆向循環(huán)操作,也可以枚舉指定節(jié)點的子節(jié)點。而調(diào)用 appendChild() 、 insertBefore() 、 removeChild() replaceChild() 方法可以改變一個節(jié)點的子節(jié)點從而改變文檔樹。

    需要指出的是, childNodes[] 的值實際上是一個 NodeList 對象。因此,可以通過遍歷 childNodes[] 數(shù)組的每個元素,來枚舉一個給定節(jié)點的所有子節(jié)點;通過遞歸,可以枚舉樹中的所有節(jié)點。下表列出了 Node 對象的一些常用屬性和方法:

    Node 對象常用屬性:

    屬性

    描述

    attributes

    如果該節(jié)點是一個 Element ,則以 NamedNodeMap 形式返回該元素的屬性。

    childNodes

    Node[] 的形式存放當(dāng)前節(jié)點的子節(jié)點。如果沒有子節(jié)點,則返回空數(shù)組。

    firstChild

    Node 的形式返回當(dāng)前節(jié)點的第一個子節(jié)點。如果沒有子節(jié)點,則為 null

    lastChild

    Node 的形式返回當(dāng)前節(jié)點的最后一個子節(jié)點。如果沒有子節(jié)點,則為 null 。

    nextSibling

    Node 的形式返回當(dāng)前節(jié)點的兄弟下一個節(jié)點。如果沒有這樣的節(jié)點,則返回 null 。

    nodeName

    節(jié)點的名字, Element 節(jié)點則代表 Element 的標(biāo)記名稱。

    nodeType

    代表節(jié)點的類型。

    parentNode

    Node 的形式返回當(dāng)前節(jié)點的父節(jié)點。如果沒有父節(jié)點,則為 null

    previousSibling

    Node 的形式返回緊挨當(dāng)前節(jié)點、位于它之前的兄弟節(jié)點。如果沒有這樣的節(jié)點,則返回 null 。

    Node 對象常用方法:

    方法

    描述

    appendChild()

    通過把一個節(jié)點增加到當(dāng)前節(jié)點的 childNodes[] 組,給文檔樹增加節(jié)點。

    cloneNode()

    復(fù)制當(dāng)前節(jié)點,或者復(fù)制當(dāng)前節(jié)點以及它的所有子孫節(jié)點。

    hasChildNodes()

    如果當(dāng)前節(jié)點擁有子節(jié)點,則將返回 true 。

    insertBefore()

    給文檔樹插入一個節(jié)點,位置在當(dāng)前節(jié)點的指定子節(jié)點之前。如果該節(jié)點已經(jīng)存在,則刪除之再插入到它的位置。

    removeChild()

    從文檔樹中刪除并返回指定的子節(jié)點。

    replaceChild()

    從文檔樹中刪除并返回指定的子節(jié)點,用另一個節(jié)點替換它。

    接下來,讓我們使用上述的 DOM 應(yīng)用編程接口,來試著操作 HTML 文檔。

    A 、遍歷文檔的節(jié)點

    DOM 把一個 HTML 文檔視為樹,因此,遍歷整個樹是應(yīng)該是家常便飯。跟之前說過的一樣,這里我們提供兩個遍歷樹的例子。通過它,我們能夠?qū)W會如何使用 childNodes[] firstChile 、 lastChild 、 nextSibling 、 previousSibling 遍歷整棵樹。

    例子 1-- sample3_1.htm

    這個例子使用了 childNodes[] 和遞歸方式來遍歷整個文檔,統(tǒng)計文檔中出現(xiàn)的 Element 元素總數(shù),并把 Element 標(biāo)記名全部打印出來。需要特別注意的是,在使用 DOM 時,必須等文檔被裝載完畢再執(zhí)行遍歷等行為操作文檔。 sample3_1.htm 具體代碼如下:

    <html>

    <head>

    <meta http-equiv="Content-Type" content="text/html; charset=gb2312">

    <title> 無標(biāo)題文檔 </title>

    <script language="javascript">

    var elementName = ""; // 全局變量,保存 Element 標(biāo)記名,使用完畢要清空

    function countTotalElement(node) { // 參數(shù) node 是一個 Node 對象

    ?????? var total = 0;

    ?????? if(node.nodeType == 1) { // 檢查 node 是否為 Element 對象

    ????????????? total++;???????????????? // 如果是,計數(shù)器加 1

    ????????????? elementName = elementName + node.tagName + "\r\n"; // 保存標(biāo)記名

    ?????? }

    ?????? var childrens = node.childNodes;???????? // 獲取 node 的全部子節(jié)點

    ?????? for(var i=0;i<childrens.length;i++) {

    ????????????? total += countTotalElement(childrens[i]); // 在每個子節(jié)點上進行遞歸操作

    ?????? }

    ?????? return total;

    }

    </script>

    </head>

    <body>

    <a href="javascript:void(0)"

    onClick="alert(' 標(biāo)記總數(shù): ' + countTotalElement(document) + '\r\n 全部標(biāo)記如下: \r\n' + elementName);elementName='';"> 開始統(tǒng)計 </a>

    </body>

    </html>

    運行效果如下:

    遍歷文檔_1.jpg 遍歷文檔_2.jpg???????????????

    例子 2 – sample3_2.htm

    接下來使用 firstChile 、 lastChild 、 nextSibling previousSibling 遍歷整個文檔樹。修改一下 countTotalElement 函數(shù),其他跟 sample3_1.htm 一樣:

    function countTotalElement(node) { // 參數(shù) node 是一個 Node 對象

    ?????? var total = 0;

    ?????? if(node.nodeType == 1) { // 檢查 node 是否為 Element 對象

    ????????????? total++;???????????????? // 如果是,計數(shù)器加 1

    ????????????? elementName = elementName + node.tagName + "\r\n"; // 保存標(biāo)記名

    ?????? }

    ?????? var childrens = node.childNodes;???????? // 獲取 node 的全部子節(jié)點

    ?????? for(var m=node.firstChild; m!=null;m=m.nextSibling) {

    ????????????? total += countTotalElement(m); // 在每個子節(jié)點上進行遞歸操作

    ?????? }

    ?????? return total;

    }

    B 、搜索文檔中特定的元素

    在使用 DOM 的過程中,有時候需要定位到文檔中的某個特定節(jié)點,或者具有特定類型的節(jié)點列表。這種情況下,可以調(diào)用 Document 對象的 getElementsByTagName() getElementById() 方法來實現(xiàn)。

    document.getElementsByTagName() 返回文檔中具有指定標(biāo)記名的全部 Element 節(jié)點數(shù)組(也是 NodeList 類型)。 Element 出現(xiàn)在數(shù)組中的順序就是他們在文檔中出現(xiàn)的順序。傳遞給 getElementsByTagName() 的參數(shù)忽略大小寫。比如,想定位到第一個 <table> 標(biāo)記,可以這樣寫: document.getElementsByTagName(“table”)[0] 。例外的,可以使用 document.body 定位到 <body> 標(biāo)記,因為它是唯一的。

    getElementsByTagName() 返回的數(shù)組取決于文檔。一旦文檔改變,返回結(jié)果也立即改變。相比, getElementById() 則比較靈活,可以隨時定位到目標(biāo),只是要實現(xiàn)給目標(biāo)元素一個唯一的 id 屬性值。這個我們在《 AJAX 開發(fā)簡略》的“級聯(lián)菜單”例子中已經(jīng)使用過了。

    Element 對象也支持 getElementsByTagName() getElementById() 。不同的是,搜索領(lǐng)域只針對調(diào)用者的子節(jié)點。

    C 、修改文檔內(nèi)容

    遍歷整棵文檔樹、搜索特定的節(jié)點,我們最終目的之一是要修改文檔內(nèi)容。接下來的三個例子將使用 Node 的幾個常用方法,來演示如何修改文檔內(nèi)容。

    例子 3 -- sample4_1.htm

    這個例子包含三個文本節(jié)點和一個按鈕。點擊按鈕后,三個文本節(jié)點和按鈕的順序?qū)⒈活嵉埂3绦蚴褂昧?/span> Node appendChild() removeChild() 方法。

    <html>

    <head>

    <meta http-equiv="Content-Type" content="text/html; charset=gb2312">

    <title> 無標(biāo)題文檔 </title>

    <script language="javascript">

    ?????? function reverseNode(node) { // 顛倒節(jié)點 node 的順序

    ????????????? var kids = node.childNodes; // 獲取子節(jié)點列表

    ????????????? var kidsNum = kids.length; // 統(tǒng)計子節(jié)點總數(shù)

    ????????????? for(var i=kidsNum-1;i>=0;i--) { // 逆向遍歷子節(jié)點列表

    ???????????????????? var c = node.removeChild(kids[i]); // 刪除指定子節(jié)點,保存在 c

    ???????????????????? node.appendChild(c); // c 放在新位置上

    ????????????? }

    ?????? }

    </script>

    </head>

    <body>

    <p> 第一行 </p>

    <p> 第二行 </p>

    <p> 第三行 </p>

    <p><input type="button" name="reverseGo" value=" 顛倒 "

    onClick="reverseNode(document.body)"></p>

    </body>

    </html>

    修改文檔_1.jpg 修改文檔_2.jpg?????????????

    例子 4-- sample4_2.htm

    例子 1 通過直接操作 body 的子節(jié)點來修改文檔。在 HTML 文檔中,布局和定位常常通過表格 <table> 來實現(xiàn)。因此,例子 4 將演示操作表格內(nèi)容,將表格的四個單元行順序顛倒。如果沒有使用 <tbody> 標(biāo)簽,則 <table> 把全部的 <tr> 當(dāng)做是屬于一個子節(jié)點 <tbody> ,所以我們采用數(shù)組緩存的方式,把行數(shù)據(jù)顛倒一下。這個例子同時也演示了如何使用 DOM 創(chuàng)建表格單元行。

    <html>

    <head>

    <meta http-equiv="Content-Type" content="text/html; charset=gb2312">

    <title> 無標(biāo)題文檔 </title>

    <script language="javascript">

    function reverseTable() {

    ?????? var node = document.getElementsByTagName("table")[0]; // 第一個表格

    ?????? var child = node.getElementsByTagName("tr"); // 取得表格內(nèi)的所有行

    ?????? var newChild = new Array(); // 定義緩存數(shù)組,保存行內(nèi)容

    ?????? for(var i=0;i<child.length;i++) {

    ????????????? newChild[i] = child[i].firstChild.innerHTML;

    ?????? }

    ?????? node.removeChild(node.childNodes[0]); // 刪除全部單元行

    ?????? var header = node.createTHead(); // 新建表格行頭

    ?????? for(var i=0;i<newChild.length;i++) {

    ????????????? var headerrow = header.insertRow(i); // 插入一個單元行

    ????????????? var cell = headerrow.insertCell(0); // 在單元行中插入一個單元格

    ????????????? // 在單元格中創(chuàng)建 TextNode 節(jié)點

    ????????????? cell.appendChild(document.createTextNode(newChild[newChild.length-i-1]));

    ?????? }

    }

    </script>

    </head>

    <body>

    <table width="200" border="1" cellpadding="4" cellspacing="0">

    ??? <tr>

    ??????? <td height="25"> 第一行 </td>

    ??? </tr>

    ??? <tr>

    ??????? <td height="25"> 第二行 </td>

    ??? </tr>

    ??? <tr>

    ??????? <td height="25"> 第三行 </td>

    ??? </tr>

    ??? <tr>

    ??????? <td height="25"> 第四行 </td>

    ??? </tr>

    </table>

    <br>

    <input type="button" name="reverse" value=" 開始顛倒 " onClick="reverseTable()">

    </body>

    </html>

    ???? 修改文檔_3.jpg修改文檔_4.jpg

    例子 5 -- sample4_3.htm

    正如我們在 Node 節(jié)點介紹部分所指出的那樣, appendChild() 、 replaceChild() 、 removeChild() insertBefore() 方法會立即改變文檔的結(jié)構(gòu)。下面的例子包含兩個表格,我們試著把表格二的內(nèi)容替換表格一的內(nèi)容。

    <html>

    <head>

    <meta http-equiv="Content-Type" content="text/html; charset=gb2312">

    <title> 無標(biāo)題文檔 </title>

    <script language="javascript">

    function replaceContent() {

    ?????? var table1 = document.getElementsByTagName("table")[0];

    ?????? var table2 = document.getElementsByTagName("table")[1];

    ?????? var kid1 = table1.firstChild.firstChild.firstChild; // 定位到 <td> 節(jié)點

    ?????? var kid2 = table2.firstChild.firstChild.firstChild; // 定位到 <td> 節(jié)點

    ?????? var repKid = kid2.firstChild; // 定位到表格二 <td> 內(nèi)含的 TextNode 節(jié)點

    ?????? try {

    ????????????? // 用表格二的單元格內(nèi)容替換表格一的單元格內(nèi)容,表格二變成沒有單元格內(nèi)容

    ????????????? kid1.replaceChild(repKid,kid1.firstChild);

    ????????????? // 下面注釋如果開放,將出現(xiàn) object error ,因為表格二已經(jīng)被改變

    ????????????? //kid2.replaceChild(kid1.firstChild,kid2.firstChild);

    ?????? }catch(e){

    ????????????? alert(e);

    ?????? }

    }

    </script>

    </head>

    <body>

    <table width="200" border="1" cellspacing="0" cellpadding="0">

    <tbody>

    ??? <tr>

    ??????? <td> 表格一 </td>

    ??? </tr>

    </tbody>

    </table>

    <br>

    <table width="200" border="1" cellspacing="0" cellpadding="0">

    <tbody>

    ??? <tr>

    ??????? <td> 表格二 </td>

    ??? </tr>

    </tbody>

    </table>

    <br>

    <input type="button" name="replaceNode" value=" 替換 " onClick="replaceContent()">

    </body>

    </html>

    ???? 修改文檔_5.jpg修改文檔_6.jpg

    注意,當(dāng)執(zhí)行 kid1.replaceChild(repKid,kid1.firstChild); 的時候, table2 的子節(jié)點已經(jīng)被轉(zhuǎn)移到 table1 了, table2 已經(jīng)沒有子節(jié)點,不能再調(diào)用 table2 的子節(jié)點。看看代碼的注釋,試著運行一下,應(yīng)該就知道文檔是怎么改變的了。

    D 、往文檔添加新內(nèi)容

    在學(xué)會遍歷、搜索、修改文檔之后,我們現(xiàn)在試著網(wǎng)文檔添加新的內(nèi)容。其實沒有什么新意,只是利用我們上述提到的 Node 的屬性和方法而已,還是操作 <table> 標(biāo)記的內(nèi)容。有新意的是,我們要實現(xiàn)一個留言簿。是的,留言簿,你可以往里面留言,只是不能刷新噢。

    例子 6 – sample5_1.htm

    <html>

    <head>

    <meta http-equiv="Content-Type" content="text/html; charset=gb2312">

    <title> 無標(biāo)題文檔 </title>

    <script language="javascript">

    function insertStr() {

    ?????? var f = document.form1;

    ?????? var value = f.str.value;

    ?????? if(value!="") {

    ????????????? // 從最終的 TextNode 節(jié)點開始,慢慢形成 <tbody> 結(jié)構(gòu)

    ????????????? var text = document.createTextNode(value); // 新建一個 TextNode 節(jié)點

    ????????????? var td = document.createElement("td"); // 新建一個 td 類型的 Element 節(jié)點

    ????????????? var tr = document.createElement("tr"); // 新建一個 tr 類型的 Element 節(jié)點

    ????????????? var tbody = document.createElement("tbody"); // 新建一個 tbody 類型的 Element 節(jié)點

    ????????????? td.appendChild(text); // 將節(jié)點 text 加入 td

    ????????????? tr.appendChild(td); // 將節(jié)點 td 加入 tr

    ????????????? tbody.appendChild(tr); // 將節(jié)點 tr 加入 tbody

    ????????????? var parNode = document.getElementById("table1"); // 定位到 table

    ????????????? parNode.insertBefore(tbody,parNode.firstChild); // 將節(jié)點 tbody 插入到節(jié)點頂部

    ????????????? //parNode.appendChild(tbody); // 將節(jié)點 tbody 加入節(jié)點尾部

    ?????? }

    }

    </script>

    </head>

    <body>

    <form name="form1" method="post" action="">

    ??? <input name="str" type="text" id="str" value="">

    ??? <input name="insert" type="button" id="insert" value=" 留言 " onClick="insertStr()">

    </form>

    <table width="400" border="1" cellspacing="0" cellpadding="0" id="table1">

    <tbody>

    ??? <tr>

    ??????? <td height="25"> 網(wǎng)友留言列表: </td>

    ??? </tr>

    </tbody>

    </table>

    </body>

    </html>

    我們之前說過, <table> 的子節(jié)點是 <tbody> , <tbody> 的子節(jié)點才是 <tr> , <tr> <td> 的父節(jié)點,最后 <td> 內(nèi)部的 TextNode 節(jié)點。所以,往 <table> 增加單元格行要逐級形成,就像往樹里面添加一個枝椏一樣,要有葉子有徑??纯?,這個留言簿是不是很簡單啊。這個例子同時也演示了往 <table> 表格標(biāo)記里面增加內(nèi)容的另一種方法。

    添加文檔內(nèi)容_1.jpg 添加文檔內(nèi)容_2.jpg
    E
    使用 DOM 操作 XML 文檔

    在數(shù)據(jù)表示方面, XML 文檔更加結(jié)構(gòu)化。 DOM 在支持 HTML 的基礎(chǔ)上提供了一系列的 API ,支持針對 XML 的訪問和操作。利用這些 API ,我們可以從 XML 中提取信息,動態(tài)的創(chuàng)建這些信息的 HTML 呈現(xiàn)文檔。處理 XML 文檔,通常遵循“加載 XML 文檔 à 提取信息 à 加工信息 à 創(chuàng)建 HTML 文檔”的過程。下面的例子演示了如何加載并處理 XML 文檔。

    這個例子包含兩個 JS 函數(shù)。 loadXML() 負(fù)責(zé)加載 XML 文檔,其中既包含加載 XML 文檔的 2 DOM 代碼,又有實現(xiàn)同樣操作的 Microsoft 專有 API 代碼。需要提醒注意的是,文檔加載過程不是瞬間完成的,所以對 loadXML() 的調(diào)用將在加載文檔完成之前返回。因此,需要傳遞給 loadXML() 一個引用,以便文檔加載完成后調(diào)用。

    例子中的另外一個函數(shù) makeTable() ,則在 XML 文檔加載完畢之后,使用最后前介紹過的 DOM 應(yīng)用編程接口讀取 XML 文檔信息,并利用這些信息形成一個新的 table 表格。

    例子 7 -- sample6_1.htm

    <html>

    <head>

    <meta http-equiv="Content-Type" content="text/html; charset=gb2312">

    <title> 無標(biāo)題文檔 </title>

    <script language="javascript">

    function loadXML(handler) {

    ?????? var url = "employees.xml";

    ?????? if(document.implementation&&document.implementation.createDocument) {

    ????????????? var xmldoc = document.implementation.createDocument("", "", null);

    ????????????? xmldoc.onload =? handler(xmldoc, url);

    ????????????? xmldoc.load(url);

    ?????? }

    ?????? else if(window.ActiveXObject) {

    ????????????? var xmldoc = new ActiveXObject("Microsoft.XMLDOM");

    ????????????? xmldoc.onreadystatechange = function() {

    ???????????????????? if(xmldoc.readyState == 4) handler(xmldoc, url);

    ????????????? }

    ????????????? xmldoc.load(url);

    ?????? }

    }

    function makeTable(xmldoc, url) {

    ?????? var table = document.createElement("table");

    ?????? table.setAttribute("border","1");

    ?????? table.setAttribute("width","600");

    ?????? table.setAttribute("class","tab-content");

    ?????? document.body.appendChild(table);

    ?????? var caption = "Employee Data from " + url;

    ?????? table.createCaption().appendChild(document.createTextNode(caption));

    ?????? var header = table.createTHead();

    ?????? var headerrow = header.insertRow(0);

    ?????? headerrow.insertCell(0).appendChild(document.createTextNode(" 姓名 "));

    ?????? headerrow.insertCell(1).appendChild(document.createTextNode(" 職業(yè) "));

    ?????? headerrow.insertCell(2).appendChild(document.createTextNode(" 工資 "));

    ?????? var employees = xmldoc.getElementsByTagName("employee");

    ?????? for(var i=0;i<employees.length;i++) {

    ????????????? var e = employees[i];

    ????????????? var name = e.getAttribute("name");

    ????????????? var job = e.getElementsByTagName("job")[0].firstChild.data;

    ????????????? var salary = e.getElementsByTagName("salary")[0].firstChild.data;

    ????????????? var row = table.insertRow(i+1);

    ????????????? row.insertCell(0).appendChild(document.createTextNode(name));

    ????????????? row.insertCell(1).appendChild(document.createTextNode(job));

    ????????????? row.insertCell(2).appendChild(document.createTextNode(salary));

    ?????? }

    }

    </script>

    <link href="css/style.css" rel="stylesheet" type="text/css">

    </head>

    ?

    <body onLoad="loadXML(makeTable)">

    </body>

    </html>

    供讀取調(diào)用的 XML 文檔 – employees.xml

    <?xml version="1.0" encoding="gb2312"?>

    <employees>

    ?????? <employee name="J.Doe">

    ????????????? <job>Programmer</job>

    ????????????? <salary>32768</salary>

    ?????? </employee>

    ?????? <employee name="A.Baker">

    ????????????? <job>Sales</job>

    ????????????? <salary>70000</salary>

    ?????? </employee>

    ?????? <employee name="Big Cheese">

    ????????????? <job>CEO</job>

    ????????????? <salary>100000</salary>

    ?????? </employee>

    </employees>

    操作XML文檔.jpg

    處理
    XML 文檔

    脫離 XML 文檔的 AJAX 是不完整的。在本部分未完成之前,有讀者說 AJAX 改名叫 AJAH H 應(yīng)該代表 HTML 吧)比較合適。應(yīng)該承認(rèn), XML 文檔在數(shù)據(jù)的結(jié)構(gòu)化表示以及接口對接上有先天的優(yōu)勢,但也不是所有的數(shù)據(jù)都應(yīng)該用 XML 表示。有些時候單純的文本表示可能會更合適。下面先舉個 AJAX 處理返回 XML 文檔的例子再討論什么時候使用 XML 。

    7.5.1 、處理返回的 XML

    例子 8 -- sample7_1.htm

    在這個例子中,我們采用之前確定的 AJAX 開發(fā)框架,稍微修改一下 body 內(nèi)容和 processRequest 的相應(yīng)方式,將先前的 employees.xml 的內(nèi)容讀取出來并顯示。

    body 的內(nèi)容如下:

    <input type="button" name="read"

    ?value=" 讀取 XML" onClick="send_request('employees.xml')">

    processRequest() 方法修改如下:

    ?????? // 處理返回信息的函數(shù)

    ??? function processRequest() {

    ??????? if (http_request.readyState == 4) { // 判斷對象狀態(tài)

    ????????? ??if (http_request.status == 200) { // 信息已經(jīng)成功返回,開始處理信息

    ??????????????????????????? var returnObj = http_request.responseXML;

    ??????????????????????????? var xmlobj = http_request.responseXML;

    ??????????????????????????? var employees = xmlobj.getElementsByTagName("employee");

    ??????????????????????????? var feedbackStr = "";

    ??????????????????????????? for(var i=0;i<employees.length;i++) { // 循環(huán)讀取 employees.xml 的內(nèi)容

    ?????????????????????????????????? var employee = employees[i];

    ?????????????????????????????????? feedbackStr += " 員工: " + employee.getAttribute("name");

    ?????????????????????????????????? feedbackStr +=

    " 職位: " + employee.getElementsByTagName("job")[0].firstChild.data;

    ?????????????????????????????????? feedbackStr +=

    ?" 工資: " + employee.getElementsByTagName("salary")[0].firstChild.data;

    ?????????????????????????????????? feedbackStr +=? "\r\n";

    ??????????????????????????? }

    ??????????????????????????? alert(feedbackStr);

    ??????????? } else { // 頁面不正常

    ??????????????? alert(" 您所請求的頁面有異常。 ");

    ??????????? }

    ??????? }

    }

    運行一下,看來效果還不錯:
    處理返回的xml.jpg

    7.5.2 、選擇合適的 XML 生成方式

    現(xiàn)在的 web 應(yīng)用程序往往采用了 MVC 三層剝離的設(shè)計方式。 XML 作為一種數(shù)據(jù)保存、呈現(xiàn)、交互的文檔,其數(shù)據(jù)往往是動態(tài)生成的,通常由 JavaBean 轉(zhuǎn)換過來。由 JavaBean 轉(zhuǎn)換成 XML 文檔的方式有好幾種,選擇合適的轉(zhuǎn)換方式往往能達(dá)到事半功倍的效果。下面介紹兩種常用的方式,以便需要的時候根據(jù)情況取舍。

    A 、類自行序列化成 XML

    類自行序列化成 XML 即每個類都實現(xiàn)自己的 toXML() 方法,選擇合適的 API 、適當(dāng)?shù)?/span> XML 結(jié)構(gòu)、盡量便捷的生成邏輯快速生成相應(yīng)的 XML 文檔。顯然,這種方式必須要求每個類編寫專門的 XML 生成代碼,每個類只能調(diào)用自己的 toXML() 方法。應(yīng)用諸如 JDOM 等一些現(xiàn)成的 API ,可以減少不少開發(fā)投入。例子 9 是一個利用 JDOM API 形成的 toXML() 方法。

    例子 9 -- toXml() JDOM 實現(xiàn) -- Employ 類的 toXml() 方法:

    public Element toXml() {?

    ?????? Element employee = new Element(“employee”);

    ?????? Employee.setAttribute(“name”,name);

    ?????? Element jobE = new Element(“job”).addContent(job);

    ?????? employee.setContent(jobE);

    ?????? Element salaryE = new Element(“salary”).addContent(salary);

    ?????? employee.setContent(salaryE);

    ?????? return employee;

    }

    JDOM 提供了現(xiàn)成的 API ,使得序列化成 XML 的工作更加簡單,我們只需要把 toXML() 外面包裝一個 Document ,然后使用 XMLOutputter 把文檔寫入 servlet 就可以了。 toXml() 允許遞歸調(diào)用其子類的 toXML() 方法,以便生成包含子圖的 XML 文檔。

    ?????? 使用類自行序列化成 XML 的方式,要每個類都實現(xiàn)自己的 toXML() 方法,而且存在數(shù)據(jù)模型與視圖耦合的問題,即要么為每個可能的視圖編寫?yīng)毩⒌?/span> toXML() 方法,要么心甘情愿接收冗余的數(shù)據(jù),一旦數(shù)據(jù)結(jié)構(gòu)或者文檔發(fā)生改變, toXML() 就要做必要的修改。

    B 、頁面模板生成 XML 方式

    一般的,可以采用通用的頁面模板技術(shù)來生成 XML 文檔,這個 XML 文檔可以符合任何需要的數(shù)據(jù)模型,供 AJAX 靈活的調(diào)用。另外,模板可以采用任何標(biāo)記語言編寫,提高工作效率。下面是一個采用 Struts 標(biāo)簽庫編寫的 XML 文檔,輸出之前提到的 employees.xml

    Sample8_2.jsp

    <%@ page contentType="application/xml; charset=gb2312" import="Employee"%>

    <%@ page import="java.util.Collection,java.util.ArrayList"%>

    <?xml version="1.0"?>

    <%@ taglib uri="/WEB-INF/struts-logic.tld" prefix="logic" %>

    <%@ taglib uri="/WEB-INF/struts-bean.tld" prefix="bean"%>

    <%

    Employee em1 = new Employee();

    em1.setName("J.Doe");

    em1.setJob("Programmer");

    em1.setSalary("32768");

    Employee em2 = new Employee();

    em2.setName("A.Baker");

    em2.setJob("Sales");

    em2.setSalary("70000");

    Employee em3 = new Employee();

    em3.setName("Big Cheese");

    em3.setJob("CEO");

    em3.setSalary("100000");

    Collection employees = new ArrayList();

    employees.add(em1);

    employees.add(em2);

    employees.add(em3);

    pageContext.setAttribute("employees",employees);

    %>

    <employees>

    <logic:iterate name="employees" id="employee">

    ?????? <employee name="<bean:write name='employee' property='name'/>">

    ????????????? <job><bean:write name="employee" property="job"/></job>

    ????????????? <salary><bean:write name="employee" property="salary"/></salary>

    ?????? </employee>

    </logic:iterate>

    </employees>

    頁面模板生成XML.jpg
    采用頁面模板生成
    XML 方式,需要為每個需要的的數(shù)據(jù)模型建立一個對立的 JSP 文件,用來生成符合規(guī)范的 XML 文檔,而不能僅僅在類的 toXML() 方法中組織對象圖來實現(xiàn)。不過,倒是可以更加方便的確保標(biāo)記匹配、元素和屬性的順序正確以及 XML 實體正確轉(zhuǎn)義。

    參考資料中 Philip McCarthy 的文章還描述了一種 Javascript 對象標(biāo)注的生成方式,本文在此不贅述。有興趣的讀者可以自行查看了解。

    7.5.3 、如何在使用 XML 還是普通文本間權(quán)衡

    使用 XML 文檔確實有其方便之處。不過 XML 文檔的某些問題倒是要考慮一下,比如說延遲,即服務(wù)器不能立即解析 XML 文檔成為 DOM 模型。這個問題在一定程度上會影響 AJAX 要求的快速反應(yīng)能力。另外,某些情況下我們并不需要使用 XML 來表示數(shù)據(jù),比如說數(shù)據(jù)足夠簡單成只有一個字符串而已。就好像我們之前提到的數(shù)據(jù)校驗和級聯(lián)菜單的例子一樣。所以,個人認(rèn)為在下面這些情況下可以考慮使用 XML 來作為數(shù)據(jù)表示的介質(zhì):

    l???????? 數(shù)據(jù)比較復(fù)雜,需要用 XML 的結(jié)構(gòu)化方式來表示

    l???????? 不用考慮帶寬和處理效率支出

    l???????? 與系統(tǒng)其他 API 或者其他系統(tǒng)交互,作為一種數(shù)據(jù)中轉(zhuǎn)中介

    l???????? 需要特定各式的輸出視圖而文本無法表示的

    總之,要認(rèn)真評估兩種表示方式的表示成本和效率,選擇合適的合理的表示方式。

    在關(guān)于 AJAX 的系列文章的下一篇,我們將綜合使用 DOM XML ,來實現(xiàn)一個可以持久化的簡單留言簿。另外,還將試著模擬 MSN Space 的部分功能,來體會 AJAX 的魅力

    posted on 2006-09-20 17:28 保爾任 閱讀(164) 評論(0)  編輯  收藏

    只有注冊用戶登錄后才能發(fā)表評論。


    網(wǎng)站導(dǎo)航:
     

    <2025年5月>
    27282930123
    45678910
    11121314151617
    18192021222324
    25262728293031
    1234567

    常用鏈接

    留言簿(4)

    隨筆分類

    隨筆檔案

    文章分類

    文章檔案

    搜索

    •  

    最新評論

    閱讀排行榜

    評論排行榜

    主站蜘蛛池模板: 91精品成人免费国产| 韩国亚洲伊人久久综合影院| 99久久99这里只有免费的精品| 波多野结衣免费视频观看| 亚洲日本va一区二区三区| 两个人的视频高清在线观看免费 | 精品国产污污免费网站aⅴ| 亚洲国产精品久久久久网站| 国产成人一区二区三区视频免费| 亚洲AV日韩AV天堂久久| 人妻在线日韩免费视频| 国产青草视频免费观看97| 亚洲午夜精品一区二区公牛电影院| 真人做A免费观看| 亚洲校园春色小说| a级片免费观看视频| 亚洲另类激情专区小说图片| 日韩一级片免费观看| 亚洲福利精品电影在线观看| 美女尿口扒开图片免费| 免费一级毛片在线播放| 亚洲日韩国产欧美一区二区三区| 四虎国产精品永久免费网址 | 亚洲精品专区在线观看| 一级一级毛片免费播放| 免费大黄网站在线观| 九九九精品视频免费| 免费在线观看亚洲| 日本系列1页亚洲系列| 成年人在线免费看视频| 免费一级毛片在线播放视频免费观看永久| 97碰公开在线观看免费视频| 亚洲国产日韩在线人成下载| 久久电影网午夜鲁丝片免费| 亚洲国产无线乱码在线观看| 青青青国产色视频在线观看国产亚洲欧洲国产综合 | 国内一级一级毛片a免费| 另类小说亚洲色图| 亚洲精品字幕在线观看| 久久久久国产精品免费看| 亚洲国产情侣一区二区三区|