屬性呢?
當(dāng)您試圖弄清楚如何處理屬性時(shí),是否遇到一些問(wèn)題呢?前已提及,屬性確實(shí)具有自己的對(duì)象類(lèi)型,但屬性確實(shí)不是顯示它的元素的子元素,嵌套元素和文本不在同一屬性 “級(jí)別”,您將注意到,清單 2 和 3 中練習(xí)的答案沒(méi)有顯示屬性。
屬性事實(shí)上存儲(chǔ)在瀏覽器使用的對(duì)象模型中,但它們有一些特殊情況。每個(gè)元素都有可用屬性的列表,且與子對(duì)象列表是分離的。所以 div 元素可能有一個(gè)包含屬性 “id” 和另一個(gè)屬性 “class” 的列表。
記住,元素的屬性必須具有惟一的名稱(chēng),也就是說(shuō),一個(gè)元素不能有兩個(gè) “id” 或兩個(gè) “class” 屬性。這使得列表易于維護(hù)和訪問(wèn)。在下一篇文章將會(huì)看到,您可以簡(jiǎn)單調(diào)用諸如 getAttribute("id") 的方法來(lái)按名稱(chēng)獲取屬性的值。還可以用相似的方法調(diào)用來(lái)添加屬性或設(shè)置(重置)現(xiàn)有屬性的值。
值得指出的是,屬性名的惟一性使得該列表不同于子對(duì)象列表。p 元素可以有多個(gè) em 元素,所以子對(duì)象列表可以包含多個(gè)重復(fù)項(xiàng)。盡管子項(xiàng)列表和屬性列表的操作方式相似,但一個(gè)可以包含重復(fù)項(xiàng)(對(duì)象的子項(xiàng)),而一個(gè)不能(元素對(duì)象的屬性)。最后,只有元素具有屬性,所以文本對(duì)象沒(méi)有用于存儲(chǔ)屬性的附加列表。
凌亂的 HTML
在繼續(xù)之前,談到瀏覽器如何將標(biāo)記轉(zhuǎn)換為樹(shù)表示,還有一個(gè)主題值得探討,即瀏覽器如何處理不是格式良好的標(biāo)記。格式良好是 XML 廣泛使用的一個(gè)術(shù)語(yǔ),有兩個(gè)基本意思:
·每個(gè)開(kāi)始標(biāo)記都有一個(gè)與之匹配的結(jié)束標(biāo)記。所以每個(gè) <p> 在文檔中與 </p> 匹配,每個(gè) <div> 與 </div> 匹配,等等。
·最里面的開(kāi)始標(biāo)記與最里面的結(jié)束標(biāo)記相匹配,然后次里面的開(kāi)始標(biāo)記與次里面的結(jié)束標(biāo)記相匹配,依此類(lèi)推。所以 <b><i>bold and italics</b></i> 是不合法的,因?yàn)樽罾锩娴拈_(kāi)始標(biāo)記 <i> 與最里面的結(jié)束標(biāo)記 <b> 匹配不當(dāng)。要使之格式良好,要么 切換開(kāi)始標(biāo)記順序,要么切換結(jié)束標(biāo)記順序。(如果兩者都切換,則仍會(huì)出現(xiàn)問(wèn)題)。
深入研究這兩條規(guī)則。這兩條規(guī)則不僅簡(jiǎn)化了文檔的組織,還消除了不定性。是否應(yīng)先應(yīng)用粗體后應(yīng)用斜體?或恰恰相反?如果覺(jué)得這種順序和不定性不是大問(wèn)題,那么請(qǐng)記住,CSS 允許規(guī)則覆蓋其他規(guī)則,所以,例如,如果 b 元素中文本的字體不同于 i 元素中的字體,則格式的應(yīng)用順序?qū)⒆兊梅浅V匾?。因此,HTML 的格式良好性有著舉足輕重的作用。
如果瀏覽器收到了不是格式良好的文檔,它只會(huì)盡力而為。得到的樹(shù)結(jié)構(gòu)在最好情況下將是作者希望的原始頁(yè)面的近似,最壞情況下將面目全非。如果您曾將頁(yè)面加載到瀏覽器中后看到完全出乎意料的結(jié)果,您可能在看到瀏覽器結(jié)果時(shí)會(huì)猜想您的結(jié)構(gòu)應(yīng)該如何,并沮喪地繼續(xù)工作。當(dāng)然,搞定這個(gè)問(wèn)題相當(dāng)簡(jiǎn)單:確保文檔是格式良好的!如果不清楚如何編寫(xiě)標(biāo)準(zhǔn)化的 HTML,請(qǐng)咨詢(xún) 參考資料 獲得幫助。
DOM 簡(jiǎn)介
到目前為止,您已經(jīng)知道瀏覽器將 Web 頁(yè)面轉(zhuǎn)換為對(duì)象表示,可能您甚至?xí)孪耄瑢?duì)象表示是 DOM 樹(shù)。DOM 表示 Document Object Model,是一個(gè)規(guī)范,可從 World Wide Web Consortium (W3C) 獲得(您可以參閱 參考資料 中的一些 DOM 相關(guān)鏈接)。
但更重要的是,DOM 定義了對(duì)象的類(lèi)型和屬性,從而允許瀏覽器表示標(biāo)記。(本系列下一篇文章將專(zhuān)門(mén)講述在 JavaScript 和 Ajax 代碼中使用 DOM 的規(guī)范。)
文檔對(duì)象
首先,需要訪問(wèn)對(duì)象模型本身。這非常容易;要在運(yùn)行于 Web 頁(yè)面上的任何 JavaScript 代碼中使用內(nèi)置 document 變量,可以編寫(xiě)如下代碼:
var domTree = document;
當(dāng)然,該代碼本身沒(méi)什么用,但它演示了每個(gè) Web 瀏覽器使得 document 對(duì)象可用于 JavaScript 代碼,并演示了對(duì)象表示標(biāo)記的完整樹(shù)(圖 1)。
每項(xiàng)都是一個(gè)節(jié)點(diǎn)
顯然,document 對(duì)象很重要,但這只是開(kāi)始。在進(jìn)一步深入之前,需要學(xué)習(xí)另一個(gè)術(shù)語(yǔ):節(jié)點(diǎn)。您已經(jīng)知道標(biāo)記的每個(gè)部分都由一個(gè)對(duì)象表示,但它不只是一個(gè)任意的對(duì)象,它是特定類(lèi)型的對(duì)象,一個(gè) DOM 節(jié)點(diǎn)。更特定的類(lèi)型,比如文本、元素和屬性,都繼承自這個(gè)基本的節(jié)點(diǎn)類(lèi)型。所以可以有文本節(jié)點(diǎn)、元素節(jié)點(diǎn)和屬性節(jié)點(diǎn)。
如果已經(jīng)有很多 JavaScript 編程經(jīng)驗(yàn),那您可能已經(jīng)在使用 DOM 代碼了。如果到目前為止您一直在跟蹤本 Ajax 系列,那么現(xiàn)在您一定 使用 DOM 代碼有一段時(shí)間了。例如,代碼行 var number = document.getElementByIdx("phone").value; 使用 DOM 查找特定元素,然后檢索該元素的值(在本例中是一個(gè)表單字段)。所以即使您沒(méi)有意識(shí)到這一點(diǎn),但您每次將 document 鍵入 JavaScript 代碼時(shí)都會(huì)使用 DOM。
詳細(xì)解釋已經(jīng)學(xué)過(guò)的術(shù)語(yǔ),DOM 樹(shù)是對(duì)象的樹(shù),但更具體地說(shuō),它是節(jié)點(diǎn)對(duì)象的樹(shù)。在 Ajax 應(yīng)用程序中或任何其他 JavaScript 中,可以使用這些節(jié)點(diǎn)產(chǎn)生下列效果,比如移除元素及其內(nèi)容,突出顯示特定文本,或添加新圖像元素。因?yàn)槎及l(fā)生在客戶(hù)端(運(yùn)行在 Web 瀏覽器中的代碼),所以這些效果立即發(fā)生,而不與服務(wù)器通信。最終結(jié)果通常是應(yīng)用程序感覺(jué)起來(lái)響應(yīng)更快,因?yàn)楫?dāng)請(qǐng)求轉(zhuǎn)向服務(wù)器時(shí)以及解釋響應(yīng)時(shí),Web 頁(yè)面上的內(nèi)容更改不會(huì)出現(xiàn)長(zhǎng)時(shí)間的停頓。
在多數(shù)編程語(yǔ)言中,需要學(xué)習(xí)每種節(jié)點(diǎn)類(lèi)型的實(shí)際對(duì)象名稱(chēng),學(xué)習(xí)可用的屬性,并弄清楚類(lèi)型和強(qiáng)制轉(zhuǎn)換;但在 JavaScript 中這都不是必需的。您可以只創(chuàng)建一個(gè)變量,并為它分配您希望的對(duì)象(正如您已經(jīng)看到的):
var domTree = document;
var phoneNumberElement = document.getElementByIdx("phone");
var phoneNumber = phoneNumberElement.value;
沒(méi)有類(lèi)型,JavaScript 根據(jù)需要?jiǎng)?chuàng)建變量并為其分配正確的類(lèi)型。結(jié)果,從 JavaScript 中使用 DOM 變得微不足道(將來(lái)有一篇文章會(huì)專(zhuān)門(mén)講述與 XML 相關(guān)的 DOM,那時(shí)將更加巧妙)。
結(jié)束語(yǔ)
在這里,我要給您留一點(diǎn)懸念。顯然,這并非是對(duì) DOM 完全詳盡的說(shuō)明;事實(shí)上,本文不過(guò)是 DOM 的簡(jiǎn)介。DOM 的內(nèi)容要遠(yuǎn)遠(yuǎn)多于我今天介紹的這些!
本系列的下一篇文章將擴(kuò)展這些觀點(diǎn),并深入探討如何在 JavaScript 中使用 DOM 來(lái)更新 Web 頁(yè)面、快速更改 HTML 并為您的用戶(hù)創(chuàng)建更交互的體驗(yàn)。在后面專(zhuān)門(mén)講述在 Ajax 請(qǐng)求中使用 XML 的文章中,我將再次返回來(lái)討論 DOM。所以要熟悉 DOM,它是 Ajax 應(yīng)用程序的一個(gè)主要部分。
此時(shí),深入了解 DOM 將十分簡(jiǎn)單,比如詳細(xì)設(shè)計(jì)如何在 DOM 樹(shù)中移動(dòng)、獲得元素和文本的值、遍歷節(jié)點(diǎn)列表,等等,但這可能會(huì)讓您有這種印象,即 DOM 是關(guān)于代碼的,而事實(shí)上并非如此。
在閱讀下一篇文章之前,試著思考一下樹(shù)結(jié)構(gòu)并用一些您自己的 HTML 實(shí)踐一下,以查看 Web 瀏覽器是如何將 HTML 轉(zhuǎn)換為標(biāo)記的樹(shù)視圖的。此外,思考一下 DOM 樹(shù)的組織,并用本文介紹的特殊情況實(shí)踐一下:屬性、有元素混合在其中的文本、沒(méi)有文本內(nèi)容的元素(比如 img 元素)。
如果扎實(shí)掌握了這些概念,然后學(xué)習(xí)了 JavaScript 和 DOM 的語(yǔ)法(下一篇文章),則會(huì)使得響應(yīng)更為容易。
而且不要忘了,這里有清單 2 和 3 的答案,其中還包含了示例代碼!
圖 2. 清單 2 的答案
圖 3. 清單 3 的答案
聯(lián)系客服