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