欧美性猛交XXXX免费看蜜桃,成人网18免费韩国,亚洲国产成人精品区综合,欧美日韩一区二区三区高清不卡,亚洲综合一区二区精品久久

打開(kāi)APP
userphoto
未登錄

開(kāi)通VIP,暢享免費電子書(shū)等14項超值服

開(kāi)通VIP
掌握 Ajax,第 5 部分: 操縱 DOM

2006 年 4 月 27 日

上一篇中 Brett 介紹了文檔對象模型(DOM),它的元素在幕后定義了 Web 頁(yè)面。這一期文章中他將進(jìn)一步探討 DOM。了解如何創(chuàng )建、刪除和修改 DOM 樹(shù)的各個(gè)部分,了解如何實(shí)現網(wǎng)頁(yè)的即時(shí)更新!

如果閱讀過(guò)本系列的 上一篇文章,那么您就非常清楚當 Web 瀏覽器顯示網(wǎng)頁(yè)時(shí)幕后發(fā)生的一切了。前面已經(jīng)提到,當 HTML 或為頁(yè)面定義的 CSS 發(fā)送給 Web 瀏覽器時(shí),網(wǎng)頁(yè)被從文本轉化成對象模型。無(wú)論代碼簡(jiǎn)單或復雜,集中到一個(gè)文件還是分散到多個(gè)文件,都是如此。然后瀏覽器直接使用對象模型而不是您提供的文本文件。瀏覽器使用的模型稱(chēng)為文檔對象模型(Document Object Model,DOM)。它連接表示文檔中元素、屬性和文本的對象。HTML 和 CSS 中所有的樣式、值、甚至大部分空格都合并到該對象模型中。給定網(wǎng)頁(yè)的具體模型稱(chēng)為該頁(yè)面的 DOM 樹(shù)。

了解什么是 DOM 樹(shù),以及知道它如何表示 HTML 和 CSS 僅僅是控制 Web 頁(yè)面的第一步。接下來(lái)還需要了解如何處理 Web 頁(yè)面的 DOM 樹(shù)。比方說(shuō),如果向 DOM 樹(shù)中增加一個(gè)元素,這個(gè)元素就會(huì )立即出現在用戶(hù)的 Web 瀏覽器中 —— 不需要重新加載頁(yè)面。從 DOM 樹(shù)中刪除一些文本,那些文本就會(huì )從用戶(hù)屏幕上消失??梢酝ㄟ^(guò) DOM 修改用戶(hù)界面或者與用戶(hù)界面交互,這樣就提供了很強的編程能力和靈活性。一旦學(xué)會(huì )了如何處理 DOM 樹(shù),您就向實(shí)現豐富的、交互式動(dòng)態(tài)網(wǎng)站邁出了一大步。

注意,下面的討論以上一篇文章 “利用 DOM 進(jìn)行 Web 響應” 為基礎,如果沒(méi)有閱讀過(guò)那一期,請在繼續閱讀之前首先閱讀上一篇文章。

首字母縮寫(xiě)的拼讀問(wèn)題

從很多方面來(lái)說(shuō),文檔對象模型應該被稱(chēng)為文檔節點(diǎn)模型(Document Node Model,DNM)。當然,大多數人不知道節點(diǎn) 一詞的含義,而且 “DNM” 也不像 “DOM” 那么容易拼讀,所以很容易理解 W3C 為何選擇了 DOM。

跨瀏覽器、跨語(yǔ)言

文檔對象模型是一種 W3C 標準(鏈接參見(jiàn) 參考資料)。因此,所有現代 Web 瀏覽器都支持 DOM —— 至少在一定程度上支持。雖然不同的瀏覽器有一些區別,但如果使用 DOM 核心功能并注意少數特殊情況和例外,DOM 代碼就能以同樣的方式用于任何瀏覽器。修改 Opera 網(wǎng)頁(yè)的代碼同樣能用于 Apple‘s Safari?、Firefox?、Microsoft? Internet Explorer? 和 Mozilla?。

DOM 也是一種跨語(yǔ)言 的規范,換句話(huà)說(shuō),大多數主流編程語(yǔ)言都能使用它。W3C 為 DOM 定義了幾種語(yǔ)言綁定。一種語(yǔ)言綁定就是為特定語(yǔ)言定義的讓您使用 DOM 的 API。比如,可以使用為 C、Java 和 JavaScript 定義的 DOM 語(yǔ)言綁定。因此可以從這些語(yǔ)言中使用 DOM。還有幾種用于其他語(yǔ)言的語(yǔ)言綁定,盡管很多是由 W3C 以外的第三方定義的。

本系列文章主要討論 JavaScript 的 DOM 綁定。這是因為多數異步應用程序開(kāi)發(fā)都需要編寫(xiě)在 Web 瀏覽器中運行的 JavaScript 代碼。使用 JavaScript 和 DOM 可以即時(shí)修改用戶(hù)界面、響應用戶(hù)事件和輸入等等 —— 使用的完全是標準的 JavaScript。

總之,建議您也嘗試一下其他語(yǔ)言中的 DOM 綁定。比如,使用 Java 語(yǔ)言綁定不僅能處理 HTML 還可處理 XML,這些內容將在以后的文章中討論。因此本文介紹的技術(shù)還可用于 HTML 之外的其他語(yǔ)言,客戶(hù)端 JavaScript 之外的其他環(huán)境。





回頁(yè)首


節點(diǎn)的概念

節點(diǎn)是 DOM 中最基本的對象類(lèi)型。實(shí)際上,您將在本文中看到,基本上 DOM 定義的其他所有對象都是節點(diǎn)對象的擴展。但是在深入分析語(yǔ)義之前,必須了解節點(diǎn)所代表的概念,然后再學(xué)習節點(diǎn)的具體屬性和方法就非常簡(jiǎn)單了。

在 DOM 樹(shù)中,基本上一切都是節點(diǎn)。每個(gè)元素在最底層上都是 DOM 樹(shù)中的節點(diǎn)。每個(gè)屬性都是節點(diǎn)。每段文本都是節點(diǎn)。甚至注釋、特殊字符(如版權符號 ?)、DOCTYPE 聲明(如果 HTML 或者 XHTML 中有的話(huà))全都是節點(diǎn)。因此在討論這些具體的類(lèi)型之前必須清楚地把握什么是節點(diǎn)。

節點(diǎn)是……

用最簡(jiǎn)單的話(huà)說(shuō),DOM 樹(shù)中的任何事物都是節點(diǎn) 。之所以用 “事物” 這個(gè)模糊的字眼,是因為只能明確到這個(gè)程度。比如 HTML 中的元素(如 img)和 HTML 中的文本片段(如 “Scroll down for more details”)沒(méi)有多少明顯的相似之處。但這是因為您考慮的可能是每種類(lèi)型的功能,關(guān)注的是它們的不同點(diǎn)。

但是如果從另一個(gè)角度觀(guān)察,DOM 樹(shù)中的每個(gè)元素和每段文本都有一個(gè)父親,這個(gè)父節點(diǎn)可能是另一個(gè)元素(比如嵌套在 p 元素中的 img)的孩子,或者 DOM 樹(shù)中的頂層元素(這是每個(gè)文檔中都出現一次的特殊情況,即使用 html 元素的地方)。另外,元素和文本都有一個(gè)類(lèi)型。顯然,元素的類(lèi)型就是元素,文本的類(lèi)型就是文本。每個(gè)節點(diǎn)還有某種定義明確的結構:下面還有節點(diǎn)(如子元素)嗎?有兄弟節點(diǎn)(與元素或文本 “相鄰的” 節點(diǎn))嗎?每個(gè)節點(diǎn)屬于哪個(gè)文檔?

顯然,大部分內容聽(tīng)起來(lái)很抽象。實(shí)際上,說(shuō)一個(gè)元素的類(lèi)型是元素似乎有點(diǎn)冒傻氣。但是要真正認識到將節點(diǎn)作為通用對象類(lèi)型的價(jià)值,必須抽象一點(diǎn)來(lái)思考。

通用節點(diǎn)類(lèi)型

DOM 代碼中最常用的任務(wù)就是在頁(yè)面的 DOM 樹(shù)中導航。比方說(shuō),可以通過(guò)其 “id” 屬性定位一個(gè) form,然后開(kāi)始處理那個(gè) form 中內嵌的元素和文本。其中可能包含文字說(shuō)明、輸入字段的標簽、真正的 input 元素,以及其他 HTML 元素(如 img)和鏈接(a 元素)。如果元素和文本是完全不同的類(lèi)型,就必須為每種類(lèi)型編寫(xiě)完全不同的代碼。

如果使用一種通用節點(diǎn)類(lèi)型情況就不同了。這時(shí)候只需要從一個(gè)節點(diǎn)移動(dòng)到另一個(gè)節點(diǎn),只有當需要對元素或文本作某種特殊處理時(shí)才需要考慮節點(diǎn)的類(lèi)型。如果僅僅在 DOM 樹(shù)中移動(dòng),就可以與其他節點(diǎn)類(lèi)型一樣用同樣的操作移動(dòng)到元素的父節點(diǎn)或者子節點(diǎn)。只有當需要某種節點(diǎn)類(lèi)型的特殊性質(zhì)時(shí),如元素的屬性,才需要對節點(diǎn)類(lèi)型作專(zhuān)門(mén)處理。將 DOM 樹(shù)中的所有對象都看作節點(diǎn)可以簡(jiǎn)化操作。記住這一點(diǎn)之后,接下來(lái)我們將具體看看 DOM 節點(diǎn)構造應該提供什么,首先從屬性和方法開(kāi)始。





回頁(yè)首


節點(diǎn)的屬性

使用 DOM 節點(diǎn)時(shí)需要一些屬性和方法,因此我們首先來(lái)討論節點(diǎn)的屬性和方法。DOM 節點(diǎn)的屬性主要有:

  • nodeName 報告節點(diǎn)的名稱(chēng)(詳見(jiàn)下述)。
  • nodeValue 提供節點(diǎn)的 “值”(詳見(jiàn)后述)。
  • parentNode 返回節點(diǎn)的父節點(diǎn)。記住,每個(gè)元素、屬性和文本都有一個(gè)父節點(diǎn)。
  • childNodes 是節點(diǎn)的孩子節點(diǎn)列表。對于 HTML,該列表僅對元素有意義,文本節點(diǎn)和屬性節點(diǎn)都沒(méi)有孩子。
  • firstChild 僅僅是 childNodes 列表中第一個(gè)節點(diǎn)的快捷方式。
  • lastChild 是另一種快捷方式,表示 childNodes 列表中的最后一個(gè)節點(diǎn)。
  • previousSibling 返回當前節點(diǎn)之前 的節點(diǎn)。換句話(huà)說(shuō),它返回當前節點(diǎn)的父節點(diǎn)的 childNodes 列表中位于該節點(diǎn)前面的那個(gè)節點(diǎn)(如果感到迷惑,重新讀前面一句)。
  • nextSibling 類(lèi)似于 previousSibling 屬性,返回父節點(diǎn)的 childNodes 列表中的下一個(gè)節點(diǎn)。
  • attributes 僅用于元素節點(diǎn),返回元素的屬性列表。

其他少數幾種屬性實(shí)際上僅用于更一般的 XML 文檔,在處理基于 HTML 的網(wǎng)頁(yè)時(shí)沒(méi)有多少用處。

不常用的屬性

上述大部分屬性的意義都很明確,除了 nodeNamenodeValue 屬性以外。我們不是簡(jiǎn)單地解釋這兩個(gè)屬性,而是提出兩個(gè)奇怪的問(wèn)題:文本節點(diǎn)的 nodeName 應該是什么?類(lèi)似地,元素的 nodeValue 應該是什么?

如果這些問(wèn)題難住了您,那么您就已經(jīng)了解了這些屬性固有的含糊性。nodeNamenodeValue 實(shí)際上并非適用于所有 節點(diǎn)類(lèi)型(節點(diǎn)的其他少數幾個(gè)屬性也是如此)。這就說(shuō)明了一個(gè)重要概念:任何這些屬性都可能返回空值(有時(shí)候在 JavaScript 中稱(chēng)為 “未定義”)。比方說(shuō),文本節點(diǎn)的 nodeName 屬性是空值(或者在一些瀏覽器中稱(chēng)為 “未定義”),因為文本節點(diǎn)沒(méi)有名稱(chēng)。如您所料,nodeValue 返回節點(diǎn)的文本。

類(lèi)似地,元素有 nodeName,即元素名,但元素的 nodeValue 屬性值總是空。屬性同時(shí)具有 nodeNamenodeValue。下一節我還將討論這些單獨的類(lèi)型,但是因為這些屬性是每個(gè)節點(diǎn)的一部分,因此在這里有必要提一提。

現在看看 清單 1,它用到了一些節點(diǎn)屬性。


清單 1. 使用 DOM 中的節點(diǎn)屬性
                            // These first two lines get the DOM tree for the current Web page,                        //   and then the <html> element for that DOM tree                        var myDocument = document;                        var htmlElement = myDocument.documentElement;                        // What‘s the name of the <html> element? "html"                        alert("The root element of the page is " + htmlElement.nodeName);                        // Look for the <head> element                        var headElement = htmlElement.getElementsByTagName("head")[0];                        if (headElement != null) {                        alert("We found the head element, named " + headElement.nodeName);                        // Print out the title of the page                        var titleElement = headElement.getElementsByTagName("title")[0];                        if (titleElement != null) {                        // The text will be the first child node of the <title> element                        var titleText = titleElement.firstChild;                        // We can get the text of the text node with nodeValue                        alert("The page title is ‘" + titleText.nodeValue + "‘");                        }                        // After <head> is <body>                        var bodyElement = headElement.nextSibling;                        while (bodyElement.nodeName.toLowerCase() != "body") {                        bodyElement = bodyElement.nextSibling;                        }                        // We found the <body> element...                        // We‘ll do more when we know some methods on the nodes.                        }                        





回頁(yè)首


節點(diǎn)方法

接下來(lái)看看所有節點(diǎn)都具有的方法(與節點(diǎn)屬性一樣,我省略了實(shí)際上不適用于多數 HTML DOM 操作的少數方法):

  • insertBefore(newChild, referenceNode)newChild 節點(diǎn)插入到 referenceNode 之前。記住,應該對 newChild 的目標父節點(diǎn)調用該方法。
  • replaceChild(newChild, oldChild)newChild 節點(diǎn)替換 oldChild 節點(diǎn)。
  • removeChild(oldChild) 從運行該方法的節點(diǎn)中刪除 oldChild 節點(diǎn)。
  • appendChild(newChild)newChild 添加到運行該函數的節點(diǎn)之中。newChild 被添加到目標節點(diǎn)孩子列表中的末端。
  • hasChildNodes() 在調用該方法的節點(diǎn)有孩子時(shí)則返回 true,否則返回 false。
  • hasAttributes() 在調用該方法的節點(diǎn)有屬性時(shí)則返回 true,否則返回 false。

注意,大部分情況下所有這些方法處理的都是節點(diǎn)的孩子。這是它們的主要用途。如果僅僅想獲取文本節點(diǎn)值或者元素名,則不需要調用這些方法,使用節點(diǎn)屬性就可以了。清單 2清單 1 的基礎上增加了方法使用。


清單 2. 使用 DOM 中的節點(diǎn)方法
                        // These first two lines get the DOM tree for the current Web page,                        //   and then the <html> element for that DOM tree                        var myDocument = document;                        var htmlElement = myDocument.documentElement;                        // What‘s the name of the <html> element? "html"                        alert("The root element of the page is " + htmlElement.nodeName);                        // Look for the <head> element                        var headElement = htmlElement.getElementsByTagName("head")[0];                        if (headElement != null) {                        alert("We found the head element, named " + headElement.nodeName);                        // Print out the title of the page                        var titleElement = headElement.getElementsByTagName("title")[0];                        if (titleElement != null) {                        // The text will be the first child node of the <title> element                        var titleText = titleElement.firstChild;                        // We can get the text of the text node with nodeValue                        alert("The page title is ‘" + titleText.nodeValue + "‘");                        }                        // After <head> is <body>                        var bodyElement = headElement.nextSibling;                        while (bodyElement.nodeName.toLowerCase() != "body") {                        bodyElement = bodyElement.nextSibling;                        }                        // We found the <body> element...                        // Remove all the top-level <img> elements in the body                        if (bodyElement.hasChildNodes()) {                        for (i=0; i<bodyElement.childNodes.length; i++) {                        var currentNode = bodyElement.childNodes[i];                        if (currentNode.nodeName.toLowerCase() == "img") {                        bodyElement.removeChild(currentNode);                        }                        }                        }                        }                        

測試一下!

目前雖然只看到了兩個(gè)例子,清單 12,不過(guò)通過(guò)這兩個(gè)例子您應該能夠了解使用 DOM 樹(shù)能夠做什么。如果要嘗試一下這些代碼,只需要將 清單 3 拖入一個(gè) HTML 文件并保存,然后用 Web 瀏覽器打開(kāi)。


清單 3. 包含使用 DOM 的 JavaScript 代碼的 HTML 文件
                        <html>                        <head>                        <title>JavaScript and the DOM</title>                        <script language="JavaScript">                        function test() {                        // These first two lines get the DOM tree for the current Web page,                        //   and then the <html> element for that DOM tree                        var myDocument = document;                        var htmlElement = myDocument.documentElement;                        // What‘s the name of the <html> element? "html"                        alert("The root element of the page is " + htmlElement.nodeName);                        // Look for the <head> element                        var headElement = htmlElement.getElementsByTagName("head")[0];                        if (headElement != null) {                        alert("We found the head element, named " + headElement.nodeName);                        // Print out the title of the page                        var titleElement = headElement.getElementsByTagName("title")[0];                        if (titleElement != null) {                        // The text will be the first child node of the <title> element                        var titleText = titleElement.firstChild;                        // We can get the text of the text node with nodeValue                        alert("The page title is ‘" + titleText.nodeValue + "‘");                        }                        // After <head> is <body>                        var bodyElement = headElement.nextSibling;                        while (bodyElement.nodeName.toLowerCase() != "body") {                        bodyElement = bodyElement.nextSibling;                        }                        // We found the <body> element...                        // Remove all the top-level <img> elements in the body                        if (bodyElement.hasChildNodes()) {                        for (i=0; i<bodyElement.childNodes.length; i++) {                        var currentNode = bodyElement.childNodes[i];                        if (currentNode.nodeName.toLowerCase() == "img") {                        bodyElement.removeChild(currentNode);                        }                        }                        }                        }                        }                        </script>                        </head>                        <body>                        <p>JavaScript and DOM are a perfect match.                        You can read more in <i>Head Rush Ajax</i>.</p>                        <img src="http://www.headfirstlabs.com/Images/hraj_cover-150.jpg" />                        <input type="button" value="Test me!" onClick="test();" />                        </body>                        </html>                        

將該頁(yè)面加載到瀏覽器后,可以看到類(lèi)似 圖 1 所示的畫(huà)面。


圖 1. 用按鈕運行 JavaScript 的 HTML 頁(yè)面

單擊 Test me! 將看到 圖 2 所示的警告框。


圖 2. 使用 nodeValue 顯示元素名的警告框

代碼運行完成后,圖片將從頁(yè)面中實(shí)時(shí)刪除,如 圖 3 所示。


圖 3. 使用 JavaScript 實(shí)時(shí)刪除圖像





回頁(yè)首


API 設計問(wèn)題

再看一看各種節點(diǎn)提供的屬性和方法。對于那些熟悉面向對象(OO)編程的人來(lái)說(shuō),它們說(shuō)明了 DOM 的一個(gè)重要特點(diǎn):DOM 并非完全面向對象的 API。首先,很多情況下要直接使用對象的屬性而不是調用節點(diǎn)對象的方法。比方說(shuō),沒(méi)有 getNodeName() 方法,而要直接使用 nodeName 屬性。因此節點(diǎn)對象(以及其他 DOM 對象)通過(guò)屬性而不是函數公開(kāi)了大量數據。

其次,如果習慣于使用重載對象和面向對象的 API,特別是 Java 和 C++ 這樣的語(yǔ)言,就會(huì )發(fā)現 DOM 中的對象和方法命名有點(diǎn)奇怪。DOM 必須能用于 C、Java 和 JavaScript(這只是其中的幾種語(yǔ)言),因此 API 設計作了一些折衷。比如,NamedNodeMap 方法有兩種不同的形式:

  • getNamedItem(String name)
  • getNamedItemNS(Node node)

對于 OO 程序員來(lái)說(shuō)這看起來(lái)非常奇怪。兩個(gè)方法目的相同,只不過(guò)一個(gè)使用 String 參數而另一個(gè)使用 Node 參數。多數 OO API 中對這兩種版本都會(huì )使用相同的方法名。運行代碼的虛擬機將根據傳遞給方法的對象類(lèi)型決定運行哪個(gè)方法。

問(wèn)題在于 JavaScript 不支持這種稱(chēng)為方法重載 的技術(shù)。換句話(huà)說(shuō),JavaScript 要求每個(gè)方法或函數使用不同的名稱(chēng)。因此,如果有了一個(gè)名為 getNamedItem() 的接受字符串參數的方法,就不能再有另一個(gè)方法或函數也命名為 getNamedItem(),即使這個(gè)方法的參數類(lèi)型不同(或者完全不同的一組參數)。如果這樣做,JavaScript 將報告錯誤,代碼不會(huì )按照預期的方式執行。

從根本上說(shuō),DOM 有意識地避開(kāi)了方法重載和其他 OO 編程技術(shù)。這是為了保證該 API 能夠用于多種語(yǔ)言,包括那些不支持 OO 編程技術(shù)的語(yǔ)言。后果不過(guò)是要求您多記住一些方法名而已。好處是可以在任何語(yǔ)言中學(xué)習 DOM,比如 Java,并清楚同樣的方法名和編碼結構也能用于具有 DOM 實(shí)現的其他語(yǔ)言,如 JavaScript。

讓程序員小心謹慎

如果深入研究 API 設計或者僅僅非常關(guān)注 API 設計,您可能會(huì )問(wèn):“為何節點(diǎn)類(lèi)型的屬性不能適用于所有節點(diǎn)?” 這是一個(gè)很好的問(wèn)題,問(wèn)題的答案與政治及決策關(guān)系更密切,而非技術(shù)原因。簡(jiǎn)單地說(shuō),答案就是,“誰(shuí)知道!但有點(diǎn)令人惱火,不是嗎?”

屬性 nodeName 意味著(zhù)允許每種類(lèi)型的節點(diǎn)都有一個(gè)名字,但是很多情況下名字要么未定義,要么是對于程序員沒(méi)有意義的內部名(比如在 Java 中,很多情況下文本節點(diǎn)的 nodeName 被報告為 “#text”)。從根本上說(shuō),必須假設您得自己來(lái)處理錯誤。直接訪(fǎng)問(wèn) myNode.nodeName 然后使用該值是危險的,很多情況下這個(gè)值為空。因此與通常的編程一樣,程序員要謹慎從事。





回頁(yè)首


通用節點(diǎn)類(lèi)型

現在已經(jīng)介紹了 DOM 節點(diǎn)的一些特性和屬性(以及一些奇特的地方),下面開(kāi)始講述您將用到的一些特殊節點(diǎn)類(lèi)型。多數 Web 應用程序中只用到四種節點(diǎn)類(lèi)型:

  • 文檔節點(diǎn)表示整個(gè) HTML 文檔。
  • 元素節點(diǎn)表示 HTML 元素,如 aimg。
  • 屬性節點(diǎn)表示 HTML 元素的屬性,如 hrefa 元素)或 srcimg 元素)。
  • 文本節點(diǎn)表示 HTML 文檔中的文本,如 “Click on the link below for a complete set list”。這是出現在 p、ah2 這些元素中的文字。

處理 HTML 時(shí),95% 的時(shí)間是跟這些節點(diǎn)類(lèi)型打交道。因此本文的其余部分將詳細討論這些節點(diǎn)。(將來(lái)討論 XML 的時(shí)候將介紹其他一些節點(diǎn)類(lèi)型。)





回頁(yè)首


文檔節點(diǎn)

基本上所有基于 DOM 的代碼中都要用到的第一個(gè)節點(diǎn)類(lèi)型是文檔節點(diǎn)。文檔節點(diǎn) 實(shí)際上并不是 HTML(或 XML)頁(yè)面中的一個(gè)元素而是頁(yè)面本身。因此在 HTML Web 頁(yè)面中,文檔節點(diǎn)就是整個(gè) DOM 樹(shù)。在 JavaScript 中,可以使用關(guān)鍵字 document 訪(fǎng)問(wèn)文檔節點(diǎn):

                        // These first two lines get the DOM tree for the current Web page,                        //   and then the <html> element for that DOM tree                        var myDocument = document;                        var htmlElement = myDocument.documentElement;                        

JavaScript 中的 document 關(guān)鍵字返回當前網(wǎng)頁(yè)的 DOM 樹(shù)。從這里可以開(kāi)始處理樹(shù)中的所有節點(diǎn)。

也可使用 document 對象創(chuàng )建新節點(diǎn),如下所示:

  • createElement(elementName) 使用給定的名稱(chēng)創(chuàng )建一個(gè)元素。
  • createTextNode(text) 使用提供的文本創(chuàng )建一個(gè)新的文本節點(diǎn)。
  • createAttribute(attributeName) 用提供的名稱(chēng)創(chuàng )建一個(gè)新屬性。

這里的關(guān)鍵在于這些方法創(chuàng )建節點(diǎn),但是并沒(méi)有將其附加或者插入到特定的文檔中。因此,必須使用前面所述的方法如 insertBefore()appendChild() 來(lái)完成這一步。因此,可使用下面的代碼創(chuàng )建新元素并將其添加到文檔中:

                        var pElement = myDocument.createElement("p");                        var text = myDocument.createTextNode("Here‘s some text in a p element.");                        pElement.appendChild(text);                        bodyElement.appendChild(pElement);                        

一旦使用 document 元素獲得對 Web 頁(yè)面 DOM 樹(shù)的訪(fǎng)問(wèn),就可以直接使用元素、屬性和文本了。





回頁(yè)首


元素節點(diǎn)

雖然會(huì )大量使用元素節點(diǎn),但很多需要對元素執行的操作都是所有節點(diǎn)共有的方法和屬性,而不是元素特有的方法和屬性。元素只有兩組專(zhuān)有的方法:

  1. 與屬性處理有關(guān)的方法
    • getAttribute(name) 返回名為 name 的屬性值。
    • removeAttribute(name) 刪除名為 name 的屬性。
    • setAttribute(name, value) 創(chuàng )建一個(gè)名為 name 的屬性并將其值設為 value。
    • getAttributeNode(name) 返回名為 name 的屬性節點(diǎn)(屬性節點(diǎn)在 下一節 介紹)。
    • removeAttributeNode(node) 刪除與指定節點(diǎn)匹配的屬性節點(diǎn)。
  2. 與查找嵌套元素有關(guān)的方法
    • getElementsByTagName(elementName) 返回具有指定名稱(chēng)的元素節點(diǎn)列表。

這些方法意義都很清楚,但還是來(lái)看幾個(gè)例子吧。

處理屬性

處理元素很簡(jiǎn)單,比如可用 document 對象和上述方法創(chuàng )建一個(gè)新的 img 元素:

                        var imgElement = document.createElement("img");                        imgElement.setAttribute("src", "http://www.headfirstlabs.com/Images/hraj_cover-150.jpg");                        imgElement.setAttribute("width", "130");                        imgElement.setAttribute("height", "150");                        bodyElement.appendChild(imgElement);                        

現在看起來(lái)應該非常簡(jiǎn)單了。實(shí)際上,只要理解了節點(diǎn)的概念并知道有哪些方法可用,就會(huì )發(fā)現在 Web 頁(yè)面和 JavaScript 代碼中處理 DOM 非常簡(jiǎn)單。在上述代碼中,JavaScript 創(chuàng )建了一個(gè)新的 img 元素,設置了一些屬性然后添加到 HTML 頁(yè)面的 body 元素中。

查找嵌套元素

發(fā)現嵌套的元素很容易。比如,下面的代碼用于發(fā)現和刪除 清單 3 所示 HTML 頁(yè)面中的所有 img 元素:

                              // Remove all the top-level <img> elements in the body                        if (bodyElement.hasChildNodes()) {                        for (i=0; i<bodyElement.childNodes.length; i++) {                        var currentNode = bodyElement.childNodes[i];                        if (currentNode.nodeName.toLowerCase() == "img") {                        bodyElement.removeChild(currentNode);                        }                        }                        }                        

也可以使用 getElementsByTagName() 完成類(lèi)似的功能:

                                                // Remove all the top-level <img> elements in the body                        var imgElements = bodyElement.getElementsByTagName("img");                        for (i=0; i<imgElements.length; i++) {                        var imgElement = imgElements.item[i];                        bodyElement.removeChild(imgElement);                        }                        





回頁(yè)首


屬性節點(diǎn)

DOM 將屬性表示成節點(diǎn),可以通過(guò)元素的 attributes 來(lái)訪(fǎng)問(wèn)元素的屬性,如下所示:

                                                // Remove all the top-level <img> elements in the body                        var imgElements = bodyElement.getElementsByTagName("img");                        for (i=0; i<imgElements.length; i++) {                        var imgElement = imgElements.item[i];                        // Print out some information about this element                        var msg = "Found an img element!";                        var atts = imgElement.attributes;                        for (j=0; j<atts.length; j++) {                        var att = atts.item(j);                        msg = msg + "\n  " + att.nodeName + ": ‘" + att.nodeValue + "‘";                        }                        alert(msg);                        bodyElement.removeChild(imgElement);                        }                        

屬性的奇特之處

對于 DOM 來(lái)說(shuō)屬性有一些特殊的地方。一方面,屬性實(shí)際上并不像其他元素或文本那樣是元素的孩子,換句話(huà)說(shuō),屬性并不出現在元素 “之下”。同時(shí),屬性顯然和元素有一定的關(guān)系,元素 “擁有” 屬性。DOM 使用節點(diǎn)表示屬性,并允許通過(guò)元素的專(zhuān)門(mén)列表來(lái)訪(fǎng)問(wèn)屬性。因此屬性是 DOM 樹(shù)的一部分,但通常不出現在樹(shù)中。有理由說(shuō),屬性和 DOM 樹(shù)結構其他部分之間的關(guān)系有點(diǎn)模糊。

需要指出的是,attributes 屬性實(shí)際上是對節點(diǎn)類(lèi)型而非局限于元素類(lèi)型來(lái)說(shuō)的。有點(diǎn)古怪,不影響您編寫(xiě)代碼,但是仍然有必要知道這一點(diǎn)。

雖然也能使用屬性節點(diǎn),但通常使用元素類(lèi)的方法處理屬性更簡(jiǎn)單。其中包括:

  • getAttribute(name) 返回名為 name 的屬性值。
  • removeAttribute(name) 刪除名為 name 的屬性。
  • setAttribute(name, value) 創(chuàng )建一個(gè)名為 name 的屬性并將其值設為 value。

這三個(gè)方法不需要直接處理屬性節點(diǎn)。但允許使用簡(jiǎn)單的字符串屬性設置和刪除屬性及其值。





回頁(yè)首


文本節點(diǎn)

需要考慮的最后一種節點(diǎn)是文本節點(diǎn)(至少在處理 HTML DOM 樹(shù)的時(shí)候如此)?;旧贤ǔS糜谔幚砦谋竟濣c(diǎn)的所有屬性都屬于節點(diǎn)對象。實(shí)際上,一般使用 nodeValue 屬性來(lái)訪(fǎng)問(wèn)文本節點(diǎn)的文本,如下所示:

                        var pElements = bodyElement.getElementsByTagName("p");                        for (i=0; i<pElements.length; i++) {                        var pElement = pElements.item(i);                        var text = pElement.firstChild.nodeValue;                        alert(text);                        }                        

少數其他幾種方法是專(zhuān)門(mén)用于文本節點(diǎn)的。這些方法用于增加或分解節點(diǎn)中的數據:

  • appendData(text) 將提供的文本追加到文本節點(diǎn)的已有內容之后。
  • insertData(position, text) 允許在文本節點(diǎn)的中間插入數據。在指定的位置插入提供的文本。
  • replaceData(position, length, text) 從指定位置開(kāi)始刪除指定長(cháng)度的字符,用提供的文本代替刪除的文本。




回頁(yè)首


什么節點(diǎn)類(lèi)型?

到目前為止看到的多數代碼都假設已經(jīng)知道處理的節點(diǎn)是什么類(lèi)型,但情況并非總是如此。比方說(shuō),如果在 DOM 樹(shù)中導航并處理一般的節點(diǎn)類(lèi)型,可能就不知道您遇到了元素還是文本。也許獲得了 p 元素的所有孩子,但是不能確定處理的是文本、b 元素還是 img 元素。這種情況下,在進(jìn)一步的處理之前需要確定是什么類(lèi)型的節點(diǎn)。

所幸的是很容易就能做到。DOM 節點(diǎn)類(lèi)型定義了一些常量,比如:

  1. Node.ELEMENT_NODE 是表示元素節點(diǎn)類(lèi)型的常量。
  2. Node.ATTRIBUTE_NODE 是表示屬性節點(diǎn)類(lèi)型的常量。
  3. Node.TEXT_NODE 是表示文本節點(diǎn)類(lèi)型的常量。
  4. Node.DOCUMENT_NODE 是表示文檔節點(diǎn)類(lèi)型的常量。

還有其他一些節點(diǎn)類(lèi)型,但是對于 HTML 除了這四種以外很少用到。我有意沒(méi)有給出這些常量的值,雖然 DOM 規范中定義了這些值,永遠不要直接使用那些值,因為這正是常量的目的!

nodeType 屬性

可使用 nodeType 屬性比較節點(diǎn)和上述常量 —— 該屬性定義在 DOM node 類(lèi)型上因此可用于所有節點(diǎn),如下所示:

                        var someNode = document.documentElement.firstChild;                        if (someNode.nodeType == Node.ELEMENT_NODE) {                        alert("We‘ve found an element node named " + someNode.nodeName);                        } else if (someNode.nodeType == Node.TEXT_NODE) {                        alert("It‘s a text node; the text is " + someNode.nodeValue);                        } else if (someNode.nodeType == Node.ATTRIBUTE_NODE) {                        alert("It‘s an attribute named " + someNode.nodeName                        + " with a value of ‘" + someNode.nodeValue + "‘");                        }                        

這個(gè)例子非常簡(jiǎn)單,但說(shuō)明了一個(gè)大問(wèn)題:得到節點(diǎn)的類(lèi)型非常 簡(jiǎn)單。更有挑戰性的是知道節點(diǎn)的類(lèi)型之后確定能做什么,只要掌握了節點(diǎn)、文本、屬性和元素類(lèi)型提供了什么屬性和方法,就可以自己進(jìn)行 DOM 編程了。

好了,快結束了。

實(shí)踐中的挫折

nodeType 屬性似乎是使用節點(diǎn)的一個(gè)入場(chǎng)券 —— 允許確定要處理的節點(diǎn)類(lèi)型然后編寫(xiě)處理該節點(diǎn)的代碼。問(wèn)題在于上述 Node 常量定義不能正確地用于 Internet Explorer。因此如果在代碼中使用 Node.ELEMENT_NODE、Node.TEXT_NODE 或其他任何常量,Internet Explorer 都將返回如 圖 4 所示的錯誤。


圖 4. Internet Explorer 報告錯誤

任何時(shí)候在 JavaScript 中使用 Node 常量,Internet Explorer 都會(huì )報錯。因為多數人仍然在使用 Internet Explorer,應該避免在代碼中使用 Node.ELEMENT_NODENode.TEXT_NODE 這樣的構造。盡管據說(shuō)即將發(fā)布的新版本 Internet Explorer 7.0 將解決這個(gè)問(wèn)題,但是在 Internet Explorer 6.x 退出舞臺之前仍然要很多年。因此應避免使用 Node,要想讓您的 DOM 代碼(和 Ajax 應用程序)能用于所有主要瀏覽器,這一點(diǎn)很重要。





回頁(yè)首


結束語(yǔ)

準備成為頂尖的網(wǎng)頁(yè)設計師嗎?

如果您準備了解甚至掌握 DOM,您就會(huì )成為最頂尖的 Web 編程人員。多數 Web 程序員知道如何使用 JavaScript 編寫(xiě)圖像滾動(dòng)或者從表單中提取值,有些甚至能夠向服務(wù)器發(fā)送請求和接收響應(閱讀本系列的前幾篇文章之后您也能做到)。但膽小鬼或者沒(méi)有經(jīng)驗的人不可能做到即時(shí)修改網(wǎng)頁(yè)結構。

在本系列的上幾期文章中您已經(jīng)學(xué)習了很多?,F在,您 應該再坐等下一篇文章期待我介紹各種聰明的 DOM 樹(shù)用法?,F在的家庭作業(yè)是看看如何使用 DOM 創(chuàng )造出富有想像力的效果或者漂亮的界面。利用近幾期文章中所學(xué)的知識開(kāi)始實(shí)驗和練習??纯茨芊窠⒏杏X(jué)更與桌面應用程序接近的網(wǎng)站,對象能夠響應用戶(hù)的動(dòng)作在屏幕上移動(dòng)。

最好在屏幕上為每個(gè)對象畫(huà)一個(gè)邊界,這樣就能看到 DOM 樹(shù)中的對象在何處,然后再移動(dòng)對象。創(chuàng )建節點(diǎn)并將其添加到已有的孩子列表中,刪除沒(méi)有嵌套節點(diǎn)的空節點(diǎn),改變節點(diǎn)的 CSS 樣式,看看孩子節點(diǎn)是否會(huì )繼承這些修改??赡苄允菬o(wú)限的,每當嘗試一些新東西時(shí),就學(xué)到了一些新的知識。盡情地修改您的網(wǎng)頁(yè)吧!

在 DOM 三部曲的最后一期文章中,我 介紹如何把一些非常棒的有趣的 DOM 應用結合到編程中。我將不再是從概念上說(shuō)教和解釋 API,而會(huì )提供一些代碼。在此之前先發(fā)揮您自己的聰明才智,看看能做些什么。





回頁(yè)首


參考資料

學(xué)習

獲得產(chǎn)品和技術(shù)
  • Brett McLaughlin 所著(zhù)的 Head Rush Ajax(O‘Reilly Media, Inc.,2006 年 3 月):深入淺出地將本文中的思想印入您的腦海。

  • Java and XML, Second Edition(Brett McLaughlin,2001 年 8 月,O‘Reilly Media, Inc.):看看作者關(guān)于 XHTML 和 XML 轉換的討論。

  • JavaScript: The Definitive Guide(David Flanagan,2001 年 11 月,O‘Reilly Media, Inc.):深入了解關(guān)于使用 JavaScript 和動(dòng)態(tài) Web 頁(yè)面的各種建議。下一版將增加關(guān)于 Ajax 的兩章。

  • Head First HTML with CSS & XHTML(Elizabeth 與 Eric Freeman,2005 年 12 月,O‘Reilly Media, Inc.):進(jìn)一步了解標準 HTML 和 XHTML,以及如何將 CSS 應用于 HTML。

  • IBM 試用軟件:用這些軟件開(kāi)發(fā)您的下一個(gè)項目,可直接從 developerWorks 下載。

討論




回頁(yè)首


關(guān)于作者

Brett McLaughlin 從 Log 時(shí)代就開(kāi)始使用計算機了。(還記得那個(gè)小三角嗎?)近年來(lái),他已經(jīng)成為 Java 和 XML 社區中最受歡迎的作者和程序員之一了。他曾經(jīng)在 Nextel Communications 實(shí)現過(guò)復雜的企業(yè)系統,在 Lutris Technologies 編寫(xiě)過(guò)應用服務(wù)器,最近在 O‘Reilly Media, Inc. 繼續撰寫(xiě)和編輯這方面的圖書(shū)。Brett 最新的著(zhù)作 Head Rush Ajax,為 Ajax 帶來(lái)了獲獎的創(chuàng )新 Head First 方法。他的近作 Java 1.5 Tiger: A Developer‘s Notebook 是關(guān)于這一 Java 技術(shù)最新版本的第一部專(zhuān)著(zhù)。經(jīng)典作品 Java and XML 仍然是在 Java 語(yǔ)言中使用 XML 技術(shù)的權威著(zhù)作之一。






回頁(yè)首

本站僅提供存儲服務(wù),所有內容均由用戶(hù)發(fā)布,如發(fā)現有害或侵權內容,請點(diǎn)擊舉報。
打開(kāi)APP,閱讀全文并永久保存 查看更多類(lèi)似文章
猜你喜歡
類(lèi)似文章
第 5 部分 操縱 DOM使用 JavaScript 即時(shí)更新 Web 頁(yè)面 (2)
Web API——DOM介紹
XML DOM介紹
javascript中的NodeType、NodeValue、NodeName實(shí)例測試
DOM節點(diǎn)信息、DOM屬性、3大節點(diǎn)、替換節點(diǎn)、查找設置屬性節點(diǎn)、創(chuàng )建刪除插入節點(diǎn)、innerHTML屬性、顯示彈出窗口
JavaScript獲取節點(diǎn)類(lèi)型、節點(diǎn)名稱(chēng)和節點(diǎn)值
更多類(lèi)似文章 >>
生活服務(wù)
分享 收藏 導長(cháng)圖 關(guān)注 下載文章
綁定賬號成功
后續可登錄賬號暢享VIP特權!
如果VIP功能使用有故障,
可點(diǎn)擊這里聯(lián)系客服!

聯(lián)系客服

欧美性猛交XXXX免费看蜜桃,成人网18免费韩国,亚洲国产成人精品区综合,欧美日韩一区二区三区高清不卡,亚洲综合一区二区精品久久