DOM 變化
-
如何確認(rèn)瀏覽器是否支持 DOM 2 和 DOM 3 新增的模塊:
var supportsDOM2Core = document.implementation.hasFeature('Core', '2.0') var supportsDOM3Core = document.implementation.hasFeature('Core', '3.0') var supportsDOM2HTML = document.implementation.hasFeature('HTML', '2.0') var supportsDOM2Views = document.implementation.hasFeature('Views', '2.0') var supportsDOM2XML = document.implementation.hasFeature('XML', '2.0')
-
針對 XML 命名空間的變化
-
混合命名空間
<html xmlns="http://www.w3.org/1999/xhtml"> <head> <title> Example XHTML page </title> </head> <body> <svg xmlns="http://www/w3.org/2000/svg" version="1.1" viewBox="0 0 100 100" style="width: 100%; height: 100%"> <rect x="0" y="0" width="100" height="100" style="fill: red" /> </svg> </body> </html>
-
在 DOM 2 中,Node 類型包含下列特定于命名空間的屬性:
-
localName
:不帶命名空間前綴的節(jié)點名稱 -
namespaceURI
:命名空間 URI 或者(在未指定的情況下)null
-
prefix
:命名空間前綴或者(在未指定的情況下)null
-
-
DOM 3 引入了下列與命名空間有關(guān)的方法:
-
isDefaultNamespace(namespaceURI)
:在指定的namespaceURI
是當(dāng)前節(jié)點的默認(rèn)命名空間時返回true
-
lookupNamespaceURI(prefix)
:返回給定prefix
的命名空間。 -
lookupPrefix(namespaceURI)
:返回給定namespace
的前綴。
-
-
DOM 2 的 Document 也發(fā)生了變化,包含了下列與命名空間有關(guān)的方法:
-
createElementNS(namespaceURI, tagName)
:使用給定的tagName
創(chuàng)建一個屬于命名空間namespace
的新元素。 -
createAttributeNS(namespaceURI, attributeName)
:使用給定的attributeName
創(chuàng)建一個屬于命名空間namespaceURI
的新特性。 -
getElementsByTagNameNS(namespaceURI, tagName)
:返回屬于命名空間namespaceURI
的tagName
元素的NodeList
。
-
-
DOM 2 也為 Element 新增了一些方法:
-
getAttributeNS(namespaceURI, localName)
:取得屬于命名空間namespaceURI
且名為localName
的特性。 -
getAttributeNodeNS(namespaceURI, localName)
:取得屬于命名空間namespaceURI
且名為localName
的特性節(jié)點。 -
getElementsByTagNameNS(namespaceURI, tagName)
:返回屬于命名空間namespaceURI
的tagName
元素的NodeList
。 -
hasAttributeNS(namespaceURI, localName)
:確定當(dāng)前元素是否有一個名為localName
的特性,而且該特性的命名空間是namespaceURI
。 -
removeAttributeNS(namespaceURI, localName)
:刪除屬于命名空間namespaceURI
且名為localName
的特性。 -
setAttributeNS(namespaceURI, qualifiedName, value)
:設(shè)置屬于命名空間namespaceURI
且名為qualifiedName
的特性值為value
。 -
setAttributeNodeNS(attNode)
:設(shè)置屬于命名空間namespaceURI
的特性節(jié)點。
-
-
NamedNodeMap 類型也新增了下列與命名空間有關(guān)的方法。由于特性是通過 NamedNodeMap 表示的,因此這些方法多數(shù)情況下只針對特性使用:
-
getNamedItemNS(namespaceURI, localName)
:取得屬于命名空間namespaceURI
且名為localName
的項。 -
removeNamedItemNS(namespaceURI, localName)
:移除屬于命名空間namespaceURI
且名為localName
的項。 -
setNamedItemNS(node)
?:添加node
。這個節(jié)點已經(jīng)事先指定了命名空間信息。
-
-
-
其他方面的變化
- DocumentType 新增了三個屬性:
-
publicId
:文檔類型聲明中的信息段之一(- //W3C//DTD HTML 4.0.1//EN
) -
systemId
:文檔類型聲明中的信息段之一(http://www.w3.org/TR/html4/strict.dtd
) -
internalSubset
:訪問包含在文檔類型聲明中的額外定義。
-
- Document 類型的變化:
-
新增
importNode()
用來從一個文檔中獲取一個節(jié)點,然后將其導(dǎo)入到另一個文檔中,使其成為這個文檔結(jié)構(gòu)的一部分。- 每個節(jié)點都有一個
ownerDocument
屬性,表示所屬的文檔。如果調(diào)用appendChild()
時傳入的節(jié)點屬于不同的文檔,會導(dǎo)致錯誤。但是在調(diào)用importNode()
的時候回返回一個歸當(dāng)前文檔所有的新的節(jié)點。
- 每個節(jié)點都有一個
-
新增
defaultView
屬性,保存一個指針,指向擁有給定文檔的窗口(或框架)。IE 不支持這個屬性,但有一個等價的屬性名叫parentWindow
。因此,要確定文檔窗口,可以使用以下代碼:var parentWindow = document.defaultView || document.parentWindow
-
DOM 2 Core 為
document.implementation
對象規(guī)定了兩個新方法:-
createDocumentType()
:創(chuàng)建一個新的 DocumentType 節(jié)點。接收三個參數(shù):文檔類型名稱、publicId
、systemId
。這個方法只在創(chuàng)建新文檔時有用。var doctype = document.implementation.createDocumentType("html", "-//W3C//DTD HTML 4.01//EN", "http://www.w3.org/TR/html4/strict.dtd")
-
createDocument()
:創(chuàng)建新文檔。接收三個參數(shù):接受文檔中元素的namespaceURI
、文檔元素的標(biāo)簽名、新文檔的文檔類型。var doc = document.implementation.createDocument("http://www.w3.org/1999/xhtml", "html", doctype)
-
DOM 2 HTML 為
document.implementation
新增了一個方法:createHTMLDocument()
。這個方法的用途是創(chuàng)建一個完整的 HTML 文檔,包括html, head, title, body
元素。它只接受一個參數(shù),即新創(chuàng)建的文檔的標(biāo)題(放在title
里),返回新的 HTML 文檔。只有 Opera 和 Safari 支持這個方法。
-
- Node 類型的變化
-
添加了
isSupported()
方法:用于確定當(dāng)前節(jié)點具有什么能力。接收兩個參數(shù):特性名、特性版本號。如果瀏覽器實現(xiàn)了相應(yīng)特性,而且能夠基于給定節(jié)點執(zhí)行該特性,就返回true
。document.body.isSupported("HTML", "2.0")
-
DOM 3 引入了兩個輔助比較節(jié)點的方法:
-
isSameNode()
:接收一個節(jié)點參數(shù),并在傳入節(jié)點與引用的節(jié)點相同(即同一個對象)時返回true
。 -
isEqualNode()
:接收一個節(jié)點參數(shù),并在傳入節(jié)點與引用的節(jié)點相等(即類型相同)時返回true
。
-
-
DOM 3 針對為 DOM 節(jié)點添加額外數(shù)據(jù)引入了新方法:
-
setUserData()
:將數(shù)據(jù)指定給節(jié)點。接收三個參數(shù):要設(shè)置的鍵、實際的數(shù)據(jù)(可以是任何數(shù)據(jù)類型)、處理函數(shù)。 -
getUserData()
:接收相同的三個參數(shù),獲取數(shù)據(jù)。 - 傳入
setUserData()
中的處理函數(shù)會在帶有數(shù)據(jù)的節(jié)點被復(fù)制、刪除、重命名或引入一個文檔時調(diào)用。處理函數(shù)接收五個參數(shù):表示操作類型的數(shù)值(1 - 復(fù)制,2 - 導(dǎo)入,3 - 刪除,4 - 重命名),數(shù)據(jù)鍵、數(shù)據(jù)值、源節(jié)點和目標(biāo)節(jié)點。刪除時源節(jié)點是null
;除復(fù)制外目標(biāo)節(jié)點是null
。
-
-
- 框架的變化
- HTMLFrameElement 和 HTMLIFrameElement 在 DOM 2 中都有了一個新屬性:
contentDocument
。它包含一個指針,指向表示框架內(nèi)容的文檔對象。在此之前,無法直接通過元素取得這個文檔對象(只能使用 frames 集合)。-
contentDocument
屬性是 Document 類型的實例,因此可以像使用其他 HTML 文檔一樣使用它,包括所有屬性和方法。IE 8 之前不支持這個屬性,但是支持一個名叫contentWindow
的屬性。var iframe = document.getElementById('myIframe') var iframeDoc = iframe.contentDocument || iframe.contentWindow.document
-
- HTMLFrameElement 和 HTMLIFrameElement 在 DOM 2 中都有了一個新屬性:
- DocumentType 新增了三個屬性:
樣式
-
確定瀏覽器是否支持 DOM 2 級定義的 CSS 能力:
var supportsDOM2CSS = document.implementation.hasFeature('CSS', '2.0') var supportsDOM2CSS2 = document.implementation.hasFeature('CSS2', '2.0')
-
訪問元素的樣式:
- 任何支持
style
特性的 HTML 元素在 JavaScript 中都有一個對應(yīng)的style
屬性。這個style
對象是 CSSStyleDeclaration 的實例,包含著通過 HTML 的style
特性指定的所有樣式信息,但不包含與外部樣式表或嵌入樣式表經(jīng)層疊而來的樣式。在style
特性中指定的任何 CSS 屬性都將表現(xiàn)為這個style
對象的相應(yīng)屬性。對于使用短劃線的 CSS 屬性名,必須將其轉(zhuǎn)換成駝峰大小寫形式,才能通過 JavaScript 來訪問。- 多數(shù)情況下,都可以通過簡單地轉(zhuǎn)換屬性名的格式來實現(xiàn)轉(zhuǎn)換。其中一個不能轉(zhuǎn)換的 CSS 屬性就是
float
。DOM 2 Style 規(guī)范規(guī)定樣式對象上相應(yīng)的屬性名應(yīng)該是cssFloat
,在 IE 上是styleFloat
。 - 在混雜模式下,沒有給出度量單位的值,將默認(rèn)為 px ,但是在標(biāo)準(zhǔn)模式下,這樣的值會被忽略。
- 多數(shù)情況下,都可以通過簡單地轉(zhuǎn)換屬性名的格式來實現(xiàn)轉(zhuǎn)換。其中一個不能轉(zhuǎn)換的 CSS 屬性就是
- DOM 2 Style 規(guī)范為
style
對象定義了一些屬性和方法。這些屬性和方法在提供元素的style
特性值的同時,也可以修改樣式:-
cssText
:訪問style
特性中的 CSS 代碼(可讀可寫)。 -
length
:應(yīng)用給元素的 CSS 屬性的數(shù)量 -
parentRule
:表示 CSS 信息的 CSSRule 對象。 -
getPropertyCSSValue(propertyName)
:返回包含給定屬性值的 CSSValue 對象。- CSSValue 包含兩個屬性:
cssText
和cssValueType
;cssValueType
是一個數(shù)值常量,表示值的類型:0 - 繼承的值,1 - 基本的值,2 - 值列表, 3 - 自定義的值。
- CSSValue 包含兩個屬性:
-
getPropertyPriority(propertyName)
:如果給定的屬性使用了!important
設(shè)置,則返回important
,否則返回空字符串。 -
getPropertyValue(propertyName)
:返回給定屬性的字符串值。 -
item(index)
:返回給定位置的 CSS 屬性的名稱。 -
removeProperty(propertyName)
:從樣式中刪除給定屬性。 -
setProperty(propertyName, value, priority)
:將給定屬性設(shè)置為相應(yīng)的值,并加上優(yōu)先權(quán)標(biāo)志(important
或者一個空字符串)。
-
- DOM 2 Style 增強(qiáng)了
document.defaultView
,提供了getComputedStyle()
方法。這個方法接受兩個參數(shù):要取得計算樣式的元素和一個偽元素字符串(例如::after
)。如果不需要偽元素信息可以傳入null
。這個方法返回一個 CSSStyleDeclaration 對象,其中包含當(dāng)前元素的所有計算后的樣式。- 由于瀏覽器解釋綜合( rollup )屬性的方式不同,所以類似
border
這樣的綜合屬性,不會在所有瀏覽器中都有返回值,但是可以通過分別訪問四個邊的屬性(例如.borderLeftWidth
)得到值。 - IE 不支持
getComputedStyle()
方法,但它有一種類似的概念。在 IE 中,每個具有style
屬性的元素還有一個currentStyle
屬性。這個屬性是 CSSStyleDeclaration 的實例,包含當(dāng)前元素全部計算后的樣式。
- 由于瀏覽器解釋綜合( rollup )屬性的方式不同,所以類似
- 不能指望某個 CSS 屬性的默認(rèn)值在不同瀏覽器中是相同的,比如
visibility
屬性在有些瀏覽器中默認(rèn)值是visible
,有些是inherit
。如果你需要元素具有某個特定的默認(rèn)值,應(yīng)該手工在樣式表中指定該值。
- 任何支持
-
操作樣式表
-
CSSStyleSheet 類型表示的是樣式表,包括通過
<link>
元素包含的樣式表和在<style>
元素中定義的樣式表。它只表示樣式表,不管這些樣式表在 HTML 中是如何定義的。此外,這個對象是一套只讀接口(有一個屬性例外)。使用下列代碼確認(rèn)瀏覽器是否支持 DOM2 StyleSheet:var supportsDOM2StyleSheet = document.implementation.hasFeature('StyleSheets', '2.0')
-
CSSStyleSheet 繼承自 StyleSheet ,所以我們可以使用后者作為基礎(chǔ)接口來定義非 CSS 樣式表。從 StyleSheet 接口繼承而來的屬性如下:
-
disabled
:表示樣式表是否被禁用。這個屬性是可讀 / 可寫的,將這個屬性設(shè)置為true
可以禁用樣式表。 -
href
:如果樣式表是通過<link>
包含的,則是樣式表的 URL ,否則,是null
。 -
media
:當(dāng)前樣式表支持的所有媒體類型(MIME Type)的集合。如果集合是空列表,表示樣式表適用于所有媒體。在 IE 中,media
是一個反映<link>
和<style>
元素media
特性值的字符串。 -
ownerNode
:指向擁有當(dāng)前樣式表的節(jié)點的指針,樣式表可能是在 HTML 中通過<link>
或<style />
引入的(在 XML 中可能是通過處理指令引入的)。如果當(dāng)前樣式表是通過其他樣式表通過@import
導(dǎo)入的,則這個屬性值為null
。IE 不支持這個屬性。 -
parentStyleSheet
:在當(dāng)前樣式表是通過@import
導(dǎo)入的情況下,這個屬性是一個指向?qū)胨臉邮奖淼闹羔槨?/li> -
title
:ownerNode
中title
屬性的值。 -
type
:表示樣式表類型的字符串。CSS 是type/css
。
以上屬性,除了
disabled
之外,都是只讀的。同時,CSSStyleSheet 還支持下列屬性和方法:-
cssRules
:樣式表中包含的樣式規(guī)則的合集。IE 不支持這個屬性,但是提供了一個類似的rules
屬性。 -
ownerRules
:如果樣式表是通過@import
導(dǎo)入的,這個屬性就是一個指針,指向表示導(dǎo)入的規(guī)則;否則,值為null
。IE 不支持這個屬性。 -
deleteRule(index)
:刪除cssRules
集合中指定位置的規(guī)則。IE 不支持,但提供了一個類似的removeRule()
方法。 -
insertRule(rule, index)
:向cssRules
集合中指定的位置插入rule
字符串。IE 不支持,但提供了一個類似的addRule()
方法。
for (let i = 0; i < document.styleSheets.length; i++) { const sheet = document.styleSheets[i] console.log(sheet.href) }
-
-
可以直接通過
<link>
或<style>
元素取得 CSSStyleSheet 對象。DOM 規(guī)定了一個包含 CSSStyleSheet 對象的屬性,叫sheet
。除了 IE ,其他瀏覽器都支持這個屬性。IE 支持的是styleSheet
屬性。要想在不同瀏覽器中都能取得樣式表對象,可以使用如下代碼:function getStyleSheet (element) { return element.sheet || element.styleSheet } const link = document.getElementsByTagName('link')[0] const sheet = getStyleSheet(link)
-
-
CSSRule 對象表示樣式表中的每一條規(guī)則。實際上,CSSRule 是一個供其他多種類繼承的基類型,其中最常見的是 CSSStyleRule 類型,表示樣式表信息(其他規(guī)則還有
@import
、@font-face
、@page
和@charset
,但這些規(guī)則很少有必要通過腳本來訪問。)CSSStyleRule 對象包含以下屬性:-
cssText
:返回整條規(guī)則對應(yīng)的文本。由于瀏覽器對樣式表的內(nèi)部處理方式不同,返回的文本可能會與樣式表中實際的文本不一樣。Safari 會全部轉(zhuǎn)換為小寫,IE 不支持這個屬性。-
cssText
包含選擇符文本和圍繞樣式信息的花括號且只讀,style.cssText
只包含樣式信息且可被修改。
-
-
parentRule
:如果當(dāng)前規(guī)則是導(dǎo)入規(guī)則,這個屬性引用的就是導(dǎo)入規(guī)則;否則,這個值為null
。IE 不支持這個屬性。 -
parentStyleSheet
:當(dāng)前規(guī)則所屬的樣式表。IE 不支持這個屬性。 -
?selectorText
:返回當(dāng)前規(guī)則的選擇符文本。由于瀏覽器對樣式表的內(nèi)部處理方式不同,返回的文本可能會與樣式表中實際的文本不一樣。 -
style
:一個 CSSStyleDeclaration 對象,可以通過它設(shè)置和取得規(guī)則中特定的樣式值。 -
type
:表示規(guī)則類型的常量值。對于樣式規(guī)則,這個值是 1。IE 不支持這個屬性。
const sheet = document.styleSheets[0] const rules = sheet.cssRules || sheet.rules const rule = rules[0] console.log(rule.cssText) console.log(rule.style.cssText)
-
-
DOM 規(guī)定,要向現(xiàn)有樣式表中添加新規(guī)則,需要使用
insertRule()
方法。這個方法接受兩個參數(shù):規(guī)則文本和表示在哪里插入規(guī)則的索引:sheet.insertRule('body { background-color: #fff }', 0)
上述語句的插入的規(guī)則將成為樣式表中的第一條規(guī)則(插入到了位置 0)。
IE 8 及更早的版本支持一個類似的方法,名叫addRule()
,也接受兩個必選參數(shù):選擇符文本和 CSS 樣式信息;一個可選參數(shù):插入規(guī)則的位置:sheet.addRule('body', 'background-color: #fff', 0)
最多只能使用這個方法插入 4095 條樣式規(guī)則。
使用
deleteRule()
刪除規(guī)則。這個方法接受一個參數(shù):要刪除的規(guī)則的位置。IE 支持的類似方法叫removeRule()
,使用方法相同。
-
-
元素大小
DOM 中沒有規(guī)定如何確定頁面中元素的大小,所以下邊的內(nèi)容并不屬于 DOM 2 Style 規(guī)范。IE 最早引入了一些屬性,目前,所有主要瀏覽器都支持這些屬性。
-
偏移量( offset dimension ):包括元素在屏幕上占用的所有可見空間。元素的可見大小由其高度、寬度決定,包括所有內(nèi)邊距、滾動條和邊框大?。ú话ㄍ膺吘啵?。通過下列四個屬性可以取得元素的偏移量:
-
offsetHeight
:元素在垂直方向上占用的空間大小,以像素計。 -
offsetWidth
:元素在水平方向占用的空間大小。 -
offsetLeft
:元素的左外邊框至包含元素的左內(nèi)邊框之間的像素距離。 -
offsetTop
:元素的上外邊框至包含元素的上內(nèi)邊框之間的像素距離。-
offsetLeft
和offsetTop
與包含元素有關(guān)。包含元素的引用保存在offsetParent
屬性中。這個屬性不一定與parentNode
的值相等。例如:<td>
元素的offsetParent
是作為其祖先元素的<table>
元素,因為<table>
是在 DOM 層次中距<td>
最近的一個具有大小的元素。 - 要想知道某個元素在頁面上的偏移量,將這個元素的
offsetLeft
和offsetTop
與其offsetParent
的相同屬性相加,如此循環(huán)直至根元素,就可以得到一個基本準(zhǔn)確的值。
-
所有這些偏移量屬性都是只讀的,并且每次訪問時都要重新計算。為了減少內(nèi)存開銷,我們可以將這些偏移量保存在局部變量中。
-
-
客戶區(qū)大?。?client dimension ):元素內(nèi)容及其內(nèi)邊距所占據(jù)的空間大小。包含兩個屬性:
-
clientWidth
:元素內(nèi)容區(qū)寬度加上左右內(nèi)邊距寬度。 -
clientHeight
:元素內(nèi)容區(qū)高度加上上下內(nèi)邊距高度。
確定瀏覽器視口大?。?/p>
function getViewport () { if (document.compatMode == 'BackCompat') { // 是否運行在混雜模式 return { width: document.body.clientWidth, height: document.body.clientHeight } } else { return { width: document.documentElement.clientWidth, height: document.documentElement.clientHeight } } }
客戶區(qū)大小也是只讀的,也需要重新計算。
-
-
滾動大?。?scroll dimension ):包含滾動內(nèi)容的元素的大小。包含以下四個屬性:
-
scrollHeight
:在沒有滾動條的情況下,元素內(nèi)容的總高度。 -
?scrollWidth
:在沒有滾動條的情況下,元素內(nèi)容的總寬度。 -
scrollLeft
:被隱藏在內(nèi)容區(qū)域左側(cè)的像素數(shù)。通過設(shè)置該屬性可以改變元素的滾動位置。 -
scrollTop
:被隱藏在內(nèi)容區(qū)域上方的像素數(shù)。通過設(shè)置該屬性可以改變元素的滾動位置。
由于一些兼容性差異,在確定文檔的總高度時(包括基于視口的最小高度時),必須取得scrollWidth / clientWidth
和scrollHeight / clientHeight
中的最大值,才能保證在跨瀏覽器的環(huán)境下得到精確的結(jié)果。對于運行在混雜模式下的 IE ,要使用document.body
代替document.documentElement
。
-
-
所有的瀏覽器都提供了
getBoundingClientRect()
方法用來確定元素大小。這個方法會返回一個矩形對象,包含四個屬性:left
、top
、right
、bottom
。這些屬性給出了元素在頁面中相對于視口的位置。在 IE 及更早版本的瀏覽器中,文檔左上角的起點坐標(biāo)是 (2, 2) 而其他瀏覽器是 (0, 0) 。所以需要檢查一下位于 (0, 0) 處元素的位置:function getBoundingClientRect (element) { if (typeof arguments.callee.offset !== 'number') { var scrollTop = document.documentElement.scrollTop var temp = document.createElement('div') temp.style.cssText = 'position: absolute; left: 0; top: 0;' document.body.appendChild(temp) arguments.callee.offset = - temp.getBoundingClientRect().top - scrollTop document.body.removeChild(temp) temp = null } var rect = element.getBoundingClientRect() var offset = arguments.callee.offset return { left: rect.left + offset right: rect.right + offset top: rect.top + offset bottom: rect.bottom + offset
Poly Fill: Custom
getBoundingClientRect()
method [詳見書 P326]
遍歷
-
DOM 2 Traversal 定義了兩個用于輔助完成順序遍歷 DOM 結(jié)構(gòu)的類型:NodeIterator 和 TreeWalker 。這兩個屬性能夠基于給定的起點對 DOM 結(jié)構(gòu)進(jìn)行深度優(yōu)先遍歷操作。IE 不支持 DOM 遍歷。使用下列代碼檢測:
var supportsTraversals = document.implementation.hasFeature('Traversal', '2.0') var supportsNodeIterator = (typeof document.createNodeIterator === 'function') var supportsTreeWalker = (typeof document.createTreeWalker === 'function')
-
NodeIterator 類型是兩者中比較簡單的一個,可以使用
document.createNodeIterator()
方法創(chuàng)建它的新實例。它接收以下四個參數(shù):-
root
:想要作為搜索起點的樹中的節(jié)點。 -
whatToShow
:表示要訪問哪些節(jié)點的數(shù)字代碼。-
它的參數(shù)是一個位掩碼,通過應(yīng)用一個或多個過濾器(
filter
)來確定要訪問哪些節(jié)點。這個參數(shù)的值以常量形式在 NodeFilter 類型中定義,如下所示:-
NodeFilter.SHOW_ALL
:顯示所有類型的節(jié)點。 -
NodeFilter.SHOW_ELEMENT
:顯示元素節(jié)點。 -
NodeFilter.SHOW_ATTRIBUTE
:顯示特性節(jié)點。由于 DOM 結(jié)構(gòu)原因,實際上不能使用這個值。 -
NodeFilter.SHOW_TEXT
:顯示文本節(jié)點。 -
NodeFilter.SHOW_CDATA_SECTION
:顯示 CDATA 節(jié)點。對 HTML 頁面沒有作用。 -
NodeFilter.SHOW_ENTITY_REFERENCE
:顯示實體引用節(jié)點。對 HTML 頁面沒有作用。 -
NodeFilter.SHOW_ENTITY
:顯示實體節(jié)點。對 HTML 頁面沒有作用。 -
NodeFilter.SHOW_PROCESSING_INSTRUCTION
:顯示處理指令節(jié)點。對 HTML 頁面沒有作用。 -
NodeFilter.SHOW_COMMENT
:顯示注釋節(jié)點。 -
NodeFilter.SHOW_DOCUMENT
:顯示文檔節(jié)點。 -
NodeFilter.SHOW_DOCUMENT_TYPE
:顯示文檔類型節(jié)點。 -
NodeFilter.SHOW_DOCUMENT_FRAGMENT
:顯示文檔片段節(jié)點。對 HTML 頁面沒有作用。 -
NodeFilter.SHOW_NOTATION
:顯示符號節(jié)點。對 HTML 頁面沒有作用。
除了
SHOW_ALL
之外,可以用|
運算符組合多個選項。 -
-
-
filter
:一個 NodeFilter 對象,或者一個表示應(yīng)該接受還是拒絕某種特定節(jié)點的函數(shù)。- 每個 FilterNode 對象只有一個方法,即
acceptNode()
。如果應(yīng)該訪問給定的節(jié)點,該方法返回NodeFilter.FILTER_ACCEPT
,如果不應(yīng)該則返回NodeFilter.FILTER_SKIP
。這是一個抽象類型,不能直接創(chuàng)建它的實例。在必要時,只要創(chuàng)建一個包含acceptNode()
方法的對象,然后將這個對象傳入createNodeIterator()
中即可。
- 每個 FilterNode 對象只有一個方法,即
-
entityReferenceExpansion
:布爾值,表示是否要擴(kuò)展實體引用。這個參數(shù)在 HTML 頁面中沒有用,因為其中的實體引用不能擴(kuò)展。
NodeIterator 類型的兩個主要方法:
-
nextNode()
:向后前進(jìn)一步,當(dāng)遍歷到最后一個節(jié)點時,返回null
。 -
previousNode()
:向前倒退一步,當(dāng)遍歷到根節(jié)點時,返回null
。
例子:返回遍歷中遇到的
<li>
元素var div = document.getElementById('div1') var filter = function (node) { return node.tagName.toLowerCase() === 'li' ? NodeFilter.FILTER_ACCEPT : NodeFilter.FILTER_SKIP } var iterator = document.createNodeIterator(div, NodeFilter.SHOW_ELEMENT, filter, false) var node = iterator.nextNode() while(node !== null) { console.log(node.tagName) node = iterator.nextNode() }
-
-
TreeWalker 是 NodeIterator 的一個更高級的版本。除了包括
nextNode()
和previousNode()
在內(nèi)的相同功能之外,這個類型還提供了下列用于在不同方向上遍歷 DOM 結(jié)構(gòu)的方法。-
parentNode()
:遍歷到當(dāng)前節(jié)點的父節(jié)點。 -
firstChild()
:遍歷到當(dāng)前節(jié)點的第一個子節(jié)點。 -
lastChild()
:遍歷到當(dāng)前節(jié)點的最后一個子節(jié)點。 -
nextSibling()
:遍歷到當(dāng)前節(jié)點的下一個同輩節(jié)點。 -
previousSibling()
:遍歷到當(dāng)前節(jié)點的上一個同輩節(jié)點。
創(chuàng)建 TreeWalker 對象要使用
document.createTreeWalker()
方法,這個方法接受四個參數(shù),與document.createNodeIterator
相同。-
filter
的返回值,除了FILTER_ACCEPT
和FILTER_SKIP
之外,還可以使用FILTER_REJECT
,在 NodeIterator 中,NodeFilter.FILTER_SKIP
與NodeFilter.FILTER_REJECT
作用相同:跳過指定節(jié)點。但在 TreeWalker 中,FILTER_SKIP
會跳過相應(yīng)節(jié)點繼續(xù)前進(jìn)到子樹中的下一個節(jié)點,而FILTER_REJECT
會跳過相應(yīng)節(jié)點及該節(jié)點的整個子樹。
-
范圍
DOM 2 Traversal & Range 模塊定義了范圍( range )接口。通過范圍可以選擇文檔中的一個區(qū)域,而不必考慮節(jié)點的界限(選擇在后臺完成,對用戶是不可見的。)IE 實現(xiàn)范圍特性的方式不同。
-
DOM 2 在 Document 類型中定義了
createRange()
方法。在兼容 DOM 的瀏覽器中,這個方法屬于document
對象。檢測方法:var supportsRange = document.implementation.hasFeature('Range', '2.0') var alsoSupportsRange = (typeof document.createRange === 'function')
-
可以使用
document.createRange()
創(chuàng)建一個 Range 類型的實例。該實例包含以下屬性,他們提供了當(dāng)前范圍在文檔中的位置信息:-
startContainer
:包含范圍起點的節(jié)點(即選中區(qū)第一個節(jié)點的父節(jié)點) -
startOffset
:范圍在startContainer
中起點的偏移量。如果startContainer
是文本節(jié)點、注釋節(jié)點或 CDATA 節(jié)點,那么startOffset
就是范圍起點之前跳過的字符數(shù)量,否則,就是范圍中第一個子節(jié)點的索引。 -
endContainer
:包含范圍終點的節(jié)點(即選區(qū)中最后一個節(jié)點的父節(jié)點)。 -
endOffset
:范圍在endContainer
中終點的偏移量(與startOffset
遵循相同的取值規(guī)則)。 -
commonAncestorContainer
:startContainer
和endContainer
共同的祖先節(jié)點在文檔樹中位置最深的那個。
-
-
用 DOM 范圍實現(xiàn)簡單選擇:
selectNode()
和selectNodeContents()
。它們都接收一個參數(shù),即一個 DOM 節(jié)點。然后使用該節(jié)點中的信息來填充范圍。其中,selectNode()
方法選擇整個節(jié)點,包括子節(jié)點;selectNodeContents()
只選擇節(jié)點的子節(jié)點。var range = document.createRange() range.selectNode(document.getElementById('test')
為了更精細(xì)的控制將哪些節(jié)點包含在范圍中,還可以使用下列方法:
-
setStartBefore(refNode)
:將范圍起點設(shè)置在refNode
之前,即refNode
是范圍選區(qū)中的第一個子節(jié)點。 -
setStartAfter(refNode)
:將范圍起點設(shè)置在refNode
之后,即refNode
的下一個同輩節(jié)點是范圍選區(qū)中的第一個子節(jié)點。 -
?setEndBefore(refNode)
:將范圍終點設(shè)置在refNode
之前,即refNode
的上一個同輩節(jié)點是范圍選區(qū)中的最后一個子節(jié)點。 -
?setEndAfter(refNode)
:將范圍終點設(shè)置在refNode
之后,即refNode
是范圍選區(qū)中的最后一個子節(jié)點。
-
用 DOM 范圍實現(xiàn)復(fù)雜選擇:
setStart()
和setEnd()
。這兩個方法都接受兩個參數(shù):參照節(jié)點和偏移量,分別對應(yīng)startContainer
/endContainer
和startOffset
/endOffset
。-
操作 DOM 范圍中的內(nèi)容:創(chuàng)建范圍時,內(nèi)部會為這個范圍創(chuàng)建一個文檔片段,范圍所屬的全部節(jié)點都被添加到了這個文檔片段中。范圍會自動完善 DOM 結(jié)構(gòu),變成一個有效的 DOM 。于是,就可以使用下列方法進(jìn)行操作了:
-
deleteContents
:從文檔中刪除范圍所包含的內(nèi)容。 -
extractContents
:從文檔中移除范圍選區(qū)(返回范圍的文檔片段)。 -
cloneContents
:返回范圍中節(jié)點的副本作為文檔片段。
-
插入 DOM 范圍中的內(nèi)容:
insertNode()
折疊 DOM 范圍:
collapse()
比較 DOM 范圍:
compareBoundaryPoints()
比較是否有公共邊界(起點或終點)復(fù)制 DOM 范圍:
range.cloneRange()
-
清理 DOM 范圍:
range.detach() range = null
IE 8 及更早版本的范圍
[詳見書 P340]