摘要:方法接受一個(gè)布爾值參數(shù),表示是否執(zhí)行深復(fù)制方法不會(huì)復(fù)制添加到節(jié)點(diǎn)中的屬性,例如事件處理程序等。由于跨域安全限制,來(lái)自不同子域的頁(yè)面無(wú)法通過(guò)通信。這三個(gè)集合都是動(dòng)態(tài)的換句話說(shuō),每當(dāng)文檔結(jié)構(gòu)發(fā)生變化時(shí),它們都會(huì)得到更新。
第十章 DOM
1001、每一段標(biāo)記都可以通過(guò)樹(shù)中的一個(gè)節(jié)點(diǎn)來(lái)表示:HTML 元素通過(guò)元素節(jié)點(diǎn)表示,特性(attribute)通過(guò)特性節(jié)點(diǎn)表示,文檔類(lèi)型通過(guò)文檔類(lèi)型節(jié)點(diǎn)表示,而注釋則通過(guò)注釋節(jié)點(diǎn)表示??偣灿?12 種節(jié)點(diǎn)類(lèi)型,這些類(lèi)型都繼承自一個(gè)基類(lèi)型
1002、JavaScript 中的所有節(jié)點(diǎn)類(lèi)型都繼承自 Node 類(lèi)型,因此所有節(jié)點(diǎn)類(lèi)型都共享著相同的基本屬性和方法
1003、所有節(jié)點(diǎn)都有的最后一個(gè)屬性是 ownerDocument ,該屬性指向表示整個(gè)文檔的文檔節(jié)點(diǎn)。這種關(guān)系表示的是任何節(jié)點(diǎn)都屬于它所在的文檔,任何節(jié)點(diǎn)都不能同時(shí)存在于兩個(gè)或更多個(gè)文檔中。通過(guò)這個(gè)屬性,我們可以不必在節(jié)點(diǎn)層次中通過(guò)層層回溯到達(dá)頂端,而是可以直接訪問(wèn)文檔節(jié)點(diǎn)
1004、如果需要把節(jié)點(diǎn)放在 childNodes 列表中某個(gè)特定的位置上,而不是放在末尾,那么可以使用insertBefore() 方法。這個(gè)方法接受兩個(gè)參數(shù):要插入的節(jié)點(diǎn)和作為參照的節(jié)點(diǎn)。插入節(jié)點(diǎn)后,被插入的節(jié)點(diǎn)會(huì)變成參照節(jié)點(diǎn)的前一個(gè)同胞節(jié)點(diǎn)( previousSibling ),同時(shí)被方法返回。如果參照節(jié)點(diǎn)是null ,則 insertBefore() 與 appendChild() 執(zhí)行相同的操作
1005、 replaceChild() 方法接受的兩個(gè)參數(shù)是:要插入的節(jié)點(diǎn)和要替換的節(jié)點(diǎn)。要替換的節(jié)點(diǎn)將由這個(gè)方法返回并從文檔樹(shù)中被移除,同時(shí)由要插入的節(jié)點(diǎn)占據(jù)其位置
1006、如果只想移除而非替換節(jié)點(diǎn),可以使用 removeChild() 方法。這個(gè)方法接受一個(gè)參數(shù),即要移除的節(jié)點(diǎn)。被移除的節(jié)點(diǎn)將成為方法的返回值
1007、要使用這幾個(gè)方法必須先取得父節(jié)點(diǎn)(使用 parentNode 屬性)。另外,并不是所有類(lèi)型的節(jié)點(diǎn)都有子節(jié)點(diǎn),如果在不支持子節(jié)點(diǎn)的節(jié)點(diǎn)上調(diào)用了這些方法,將會(huì)導(dǎo)致錯(cuò)誤發(fā)生
1008、 cloneNode() ,用于創(chuàng)建調(diào)用這個(gè)方法的節(jié)點(diǎn)的一個(gè)完全相同的副本。 cloneNode() 方法接受一個(gè)布爾值參數(shù),表示是否執(zhí)行深復(fù)制
1009、cloneNode() 方法不會(huì)復(fù)制添加到 DOM 節(jié)點(diǎn)中的 JavaScript 屬性,例如事件處理程序等。這個(gè)方法只復(fù)制特性、(在明確指定的情況下也復(fù)制)子節(jié)點(diǎn),其他一切都不會(huì)復(fù)制。IE 在此存在一個(gè) bug,即它會(huì)復(fù)制事件處理程序,所以我們建議在復(fù)制之前最好先移除事件處理程序
1010、最后一個(gè)方法是 normalize() ,這個(gè)方法唯一的作用就是處理文檔樹(shù)中的文本節(jié)點(diǎn)。由于解析器的實(shí)現(xiàn)或 DOM 操作等原因,可能會(huì)出現(xiàn)文本節(jié)點(diǎn)不包含文本,或者接連出現(xiàn)兩個(gè)文本節(jié)點(diǎn)的情況。當(dāng)在某個(gè)節(jié)點(diǎn)上調(diào)用這個(gè)方法時(shí),就會(huì)在該節(jié)點(diǎn)的后代節(jié)點(diǎn)中查找上述兩種情況。如果找到了空文本節(jié)點(diǎn),則刪除它;如果找到相鄰的文本節(jié)點(diǎn),則將它們合并為一個(gè)文本節(jié)點(diǎn)
1011、雖然 DOM 標(biāo)準(zhǔn)規(guī)定 Document 節(jié)點(diǎn)的子節(jié)點(diǎn)可以是 DocumentType 、 Element 、 ProcessingIn-struction 或 Comment ,但還有兩個(gè)內(nèi)置的訪問(wèn)其子節(jié)點(diǎn)的快捷方式。第一個(gè)就是 documentElement屬性,該屬性始終指向 HTML 頁(yè)面中的 元素。另一個(gè)就是通過(guò) childNodes 列表訪問(wèn)文檔元素,但通過(guò) documentElement 屬性則能更快捷、更直接地訪問(wèn)該元素
1012、所有瀏覽器都支持 document.documentElement 和 document.body 屬性
1013、作為 HTMLDocument 的一個(gè)實(shí)例, document 對(duì)象還有一些標(biāo)準(zhǔn)的 Document 對(duì)象所沒(méi)有的屬性。這些屬性提供了 document 對(duì)象所表現(xiàn)的網(wǎng)頁(yè)的一些信息。其中第一個(gè)屬性就是 title ,包含著
1014、 URL 屬性中包含頁(yè)面完整的 URL(即地址欄中顯示的 URL), domain 屬性中只包含頁(yè)面的域名,而 referrer屬性中則保存著鏈接到當(dāng)前頁(yè)面的那個(gè)頁(yè)面的 URL。在沒(méi)有來(lái)源頁(yè)面的情況下, referrer 屬性中可能會(huì)包含空字符串。所有這些信息都存在于請(qǐng)求的 HTTP 頭部,只不過(guò)是通過(guò)這些屬性讓我們能夠在JavaScrip 中訪問(wèn)它們而已
1015、當(dāng)頁(yè)面中包含來(lái)自其他子域的框架或內(nèi)嵌框架時(shí),能夠設(shè)置 document.domain 就非常方便了。由于 跨 域 安 全 限 制 , 來(lái) 自 不 同 子 域 的 頁(yè) 面 無(wú) 法 通 過(guò) JavaScript 通 信 。 而 通 過(guò) 將 每 個(gè) 頁(yè) 面 的document.domain 設(shè)置為相同的值,這些頁(yè)面就可以互相訪問(wèn)對(duì)方包含的 JavaScript 對(duì)象了
1016、假設(shè)有一個(gè)頁(yè)面加載自 www.wrox.com,其中包含一個(gè)內(nèi)嵌框架,框架內(nèi)的頁(yè)面加載自 p2p.wrox.com。由于 document.domain 字符串不一樣,內(nèi)外兩個(gè)頁(yè)面之間無(wú)法相互訪問(wèn)對(duì)方的 JavaScript 對(duì)象。但如果將這兩個(gè)頁(yè)面的 document.domain 值都設(shè)置為 "wrox.com" ,它們之間就可以通信了。瀏覽器對(duì) domain 屬性還有一個(gè)限制,即如果域名一開(kāi)始是“松散的”(loose),那么不能將它再設(shè)置為“緊繃的”(tight)。換句話說(shuō),在將 document.domain 設(shè)置為 "wrox.com" 之后,就不能再將其設(shè)置回 "p2p.wrox.com" ,否則將會(huì)導(dǎo)致錯(cuò)誤
1017、HTMLCollection 對(duì)象還有一個(gè)方法,叫做 namedItem() ,使用這個(gè)方法可以通過(guò)元素的 name特性取得集合中的項(xiàng)。對(duì) HTMLCollection 而言,我們可以向方括號(hào)中傳入數(shù)值或字符串形式的索引值。在后臺(tái),對(duì)數(shù)值索引就會(huì)調(diào)用 item() ,而對(duì)字符串索引就會(huì)調(diào)用 namedItem()
1018、有一個(gè) document 對(duì)象的功能已經(jīng)存在很多年了,那就是將輸出流寫(xiě)入到網(wǎng)頁(yè)中的能力。這個(gè)能力體現(xiàn)在下列 4 個(gè)方法中: write() 、 writeln() 、 open() 和 close() 。其中, write() 和 writeln()方法都接受一個(gè)字符串參數(shù),即要寫(xiě)入到輸出流中的文本。 write() 會(huì)原樣寫(xiě)入,而 writeln() 則會(huì)在字符串的末尾添加一個(gè)換行符( n )。在頁(yè)面被加載的過(guò)程中,可以使用這兩個(gè)方法向頁(yè)面中動(dòng)態(tài)地加入內(nèi)容
1019、方法 open() 和 close() 分別用于打開(kāi)和關(guān)閉網(wǎng)頁(yè)的輸出流
1020、每個(gè)元素都有一或多個(gè)特性,這些特性的用途是給出相應(yīng)元素或其內(nèi)容的附加信息。操作特性的DOM 方法主要有三個(gè),分別是 getAttribute() 、 setAttribute() 和 removeAttribute()
1021、與 getAttribute() 對(duì)應(yīng)的方法是 setAttribute() ,這個(gè)方法接受兩個(gè)參數(shù):要設(shè)置的特性名和值。如果特性已經(jīng)存在, setAttribute() 會(huì)以指定的值替換現(xiàn)有的值;如果特性不存在, setAttribute()則創(chuàng)建該屬性并設(shè)置相應(yīng)的值
1022、 removeAttribute() ,這個(gè)方法用于徹底刪除元素的特性。調(diào)用這個(gè)方法不僅會(huì)清除特性的值,而且也會(huì)從元素中完全刪除特性
1023、使用 document.createElement() 方法可以創(chuàng)建新元素。這個(gè)方法只接受一個(gè)參數(shù),即要?jiǎng)?chuàng)建元素的標(biāo)簽名。這個(gè)標(biāo)簽名在 HTML 文檔中不區(qū)分大小寫(xiě),而在 XML(包括 XHTML)文檔中,則是區(qū)分大小寫(xiě)的
1024、文本節(jié)點(diǎn)由 Text 類(lèi)型表示,包含的是可以照字面解釋的純文本內(nèi)容。純文本中可以包含轉(zhuǎn)義后的HTML 字符,但不能包含 HTML 代碼
1025、可以使用 document.createTextNode() 創(chuàng)建新文本節(jié)點(diǎn),這個(gè)方法接受一個(gè)參數(shù)——要插入節(jié)點(diǎn)中的文本
1026、使用 document.createComment() 并為其傳遞注釋文本也可以創(chuàng)建注釋節(jié)點(diǎn)
1027、雖然不能把文檔片段直接添加到文檔中,但可以將它作為一個(gè)“倉(cāng)庫(kù)”來(lái)使用,即可以在里面保存將來(lái)可能會(huì)添加到文檔中的節(jié)點(diǎn)。要?jiǎng)?chuàng)建文檔片段,可以使用 document.createDocumentFragment() 方法
1028、文檔片段繼承了 Node 的所有方法,通常用于執(zhí)行那些針對(duì)文檔的 DOM操作。如果將文檔中的節(jié)點(diǎn)添加到文檔片段中,就會(huì)從文檔樹(shù)中移除該節(jié)點(diǎn),也不會(huì)從瀏覽器中再看到該節(jié)點(diǎn)。添加到文檔片段中的新節(jié)點(diǎn)同樣也不屬于文檔樹(shù)??梢酝ㄟ^(guò) appendChild() 或insertBefore() 將文檔片段中內(nèi)容添加到文檔中。在將文檔片段作為參數(shù)傳遞給這兩個(gè)方法時(shí),實(shí)際上只會(huì)將文檔片段的所有子節(jié)點(diǎn)添加到相應(yīng)位置上;文檔片段本身永遠(yuǎn)不會(huì)成為文檔樹(shù)的一部分
1029、Attr 對(duì)象有 3 個(gè)屬性: name 、 value 和 specified 。其中, name 是特性名稱(chēng)(與 nodeName 的值相同), value 是特性的值(與 nodeValue 的值相同),而 specified 是一個(gè)布爾值,用以區(qū)別特性是在代碼中指定的,還是默認(rèn)的
1030、理解 NodeList 及其“近親” NamedNodeMap 和 HTMLCollection ,是從整體上透徹理解 DOM 的關(guān)鍵所在。這三個(gè)集合都是“動(dòng)態(tài)的”;換句話說(shuō),每當(dāng)文檔結(jié)構(gòu)發(fā)生變化時(shí),它們都會(huì)得到更新。因此,它們始終都會(huì)保存著最新、最準(zhǔn)確的信息。從本質(zhì)上說(shuō),所有 NodeList 對(duì)象都是在訪問(wèn) DOM文檔時(shí)實(shí)時(shí)運(yùn)行的查詢
1031、一般來(lái)說(shuō),應(yīng)該盡量減少訪問(wèn) NodeList 的次數(shù)。因?yàn)槊看卧L問(wèn) NodeList ,都會(huì)運(yùn)行一次基于文檔的查詢。所以,可以考慮將從 NodeList 中取得的值緩存起來(lái)
1032、querySelector() 方法接收一個(gè) CSS 選擇符,返回與該模式匹配的第一個(gè)元素,如果沒(méi)有找到匹配的元素,返回 null 。
1033、querySelectorAll() 方法接收的參數(shù)與 querySelector() 方法一樣,都是一個(gè) CSS 選擇符,但返回的是所有匹配的元素而不僅僅是一個(gè)元素。這個(gè)方法返回的是一個(gè) NodeList 的實(shí)例
1034、如果傳入了瀏覽器不支持的選擇符或者選擇符中有語(yǔ)法錯(cuò)誤,querySelectorAll() 會(huì)拋出錯(cuò)誤
1035、Selectors API Level 2 規(guī)范為 Element 類(lèi)型新增了一個(gè)方法 matchesSelector() 。這個(gè)方法接收一個(gè)參數(shù),即 CSS 選擇符,如果調(diào)用元素與該選擇符匹配,返回 true ;否則,返回 false
1036、對(duì)于元素間的空格,IE9及之前版本不會(huì)返回文本節(jié)點(diǎn),而其他所有瀏覽器都會(huì)返回文本節(jié)點(diǎn)
1037、支持 getElementsByClassName() 方法的瀏覽器有 IE 9+、Firefox 3+、Safari 3.1+、Chrome 和Opera 9.5+
1038、新增了 document.hasFocus() 方法,這個(gè)方法用于確定文檔是否獲得了焦點(diǎn)
1039、使用 document.readyState 的最恰當(dāng)方式,就是通過(guò)它來(lái)實(shí)現(xiàn)一個(gè)指示文檔已經(jīng)加載完成的指示器。支持 readyState 屬性的瀏覽器有 IE4+、Firefox 3.6+、Safari、Chrome和 Opera 9+
1040、自從 IE6 開(kāi)始區(qū)分渲染頁(yè)面的模式是標(biāo)準(zhǔn)的還是混雜的,檢測(cè)頁(yè)面的兼容模式就成為瀏覽器的必要功能。IE 為此給 document 添加了一個(gè)名為 compatMode 的屬性,這個(gè)屬性就是為了告訴開(kāi)發(fā)人員瀏覽器采用了哪種渲染模式。就像下面例子中所展示的那樣,在標(biāo)準(zhǔn)模式下, document.compatMode 的值等于 "CSS1Compat" ,而在混雜模式下, document.compatMode 的值等于 "BackCompat"。
1041、HTML5規(guī)定可以為元素添加非標(biāo)準(zhǔn)的屬性,但要添加前綴 data- ,目的是為元素提供與渲染無(wú)關(guān)的信息,或者提供語(yǔ)義信息。這些屬性可以任意添加、隨便命名,只要以 data- 開(kāi)頭即可
1042、在讀模式下, innerHTML 屬性返回與調(diào)用元素的所有子節(jié)點(diǎn)(包括元素、注釋和文本節(jié)點(diǎn))對(duì)應(yīng)的 HTML 標(biāo)記。在寫(xiě)模式下, innerHTML 會(huì)根據(jù)指定的值創(chuàng)建新的 DOM樹(shù),然后用這個(gè) DOM 樹(shù)完全替換調(diào)用元素原先的所有子節(jié)點(diǎn)
1043、在寫(xiě)模式下, innerHTML 的值會(huì)被解析為 DOM 子樹(shù),替換調(diào)用元素原來(lái)的所有子節(jié)點(diǎn)。因?yàn)樗闹当徽J(rèn)為是 HTML,所以其中的所有標(biāo)簽都會(huì)按照瀏覽器處理 HTML 的標(biāo)準(zhǔn)方式轉(zhuǎn)換為元素(同樣,這里的轉(zhuǎn)換結(jié)果也因?yàn)g覽器而異)。如果設(shè)置的值僅是文本而沒(méi)有 HTML 標(biāo)簽,那么結(jié)果就是設(shè)置純文本
1044、 innerHTML 字符串一開(kāi)始(而且整個(gè))就是一個(gè)“無(wú)作用域的元素”,所以這個(gè)字符串會(huì)變成空字符串
1045、不支持 innerHTML 的元素有: