javascript
(JS基础)DOM:节点类型
Node 類型
所有節點類型都繼承于 Node 類型,因此所有節點類型都共享這相同的基本屬性和方法。
基本屬性和方法
- nodeName :節點名。對于元素類型,則是元素的標簽名(均為大寫),如"SPAN"、"DIV";對于其他類型會有不同的值,下面每個類型會分別指出。
- nodeValue :節點值。對于元素類型為null;對于其他類型會有不同的值,下面每個類型會分別指出。
- hasChildNodes() :布爾值,是否含有子節點。
- childNodes :NodeList 對象的集合,是一個類數組,實際是基于 DOM 結構動態查詢的結果。
- firstChild :等效于 childNodes[0] ;
- lastChild :等效于 childNodes[childNodes.length - 1] 。
- parentNode :指向父節點。
- previousSibling :前一個同胞節點;
- nextSibling :后一個同胞節點。
- ownerDocument :指向節點所在的整個文檔節點。
下面 4 個是比較常用的方法,但必須是含有子節點或能有子節點的節點對象才能使用:
- appendChild(newNode) :向 childNodes 集合的末尾添加一個新節點。
- removeChild(node) :移除指定的子節點,并返回被移除的節點。
- repalceChild(newNode, node) :用新節點替換原子節點,返回被替換的原節點。
- insertBefore(newNode, node) :在參照子節點(可為null)后添加新節點,返回新節點。
下面 2 個方法是所有節點都能使用:
- clone(isDeepClone?) :克隆當前節點,可以接收一個參數:是否深克隆,深克隆表示包含其所有子節點,否則只復制節點本身。
- normalize() :移除空的文本節點,并連接相鄰的文本節點。
還有一個屬性,用于表示節點的類型:
- nodeType :常量值,一共有 12 種,如 "Node.ELEMENT_NODE" 或 數字 1 ,下面每個類型會分別給出對象的值。
節點比較的方法
用于比較兩個節點,如div1.isSameNode(div2),返回結果為布爾值。以下有兩個概念:相同,表示兩個對象指向的是同一個 DOM 節點對象;相等,表示兩個對象的類型、屬性、內容等均相同,但不一定是同一個對象。
- isSameNode(node) :判斷與 node 對象是否相同,document 對象可用。
- isEqualNode(node) :判斷與 node 對象是否相等,document 對象不可用。
Document 類型
document 類型表示文檔。在瀏覽器中,document 對象是 HTMLDocument (繼承自 Document 類型) 的一個實例,表示整個 HTML 頁面。且 document 對象 是 window 對象 的一個屬性。
特征:
一般屬性
- documentElement :指向文檔中的<html>元素。
- body :指向文檔中的<body>元素。
- doctype :指向文檔中的<!DOCTYPE>元素。
- title :指向文檔中的<title>元素。
- URL :文檔的 完整 URL 。
- domain :文檔 URL 的主機名。
獲取元素的方法
- getElementById() :獲取指定 ID 的元素,不存在這返回null。
- getElementsByTagName() :獲取給定標簽名的所有元素的集合,返回 HTMLCollection 對象,該對象是一個類數組,找不到指定標簽則集合為空。
- getElementsByClassName() :獲取給定 CSS 類名的所有元素的集合,返回 HTMLCollection 對象。
- getElementsByName() :獲取給定 name 特性的所有元素的集合,返回 NodeList 。
- querySelector() :獲取給定 CSS 選擇符的第一個元素,無則返回null。
- querySelectorAll() :獲取給定 CSS 選擇符的所有元素的集合,返回 NodeList 。
特殊集合
獲取的集合都是 HTMLCollection 對象。
- anchors:包含所有待 name 特性的<a>元素
- forms:包含所有<form>元素
- images:包含所有<img>元素
- links:包含所有帶有 href 特性的<link>元素
焦點管理
HTML5 新增了 1 個屬性和 1 個方法用于輔助管理 DOM 的焦點。
- activeElement :引用 DOM 中當前獲得焦點的元素。
- hasFocus() :當前文檔是否獲得了焦點,布爾值。用于確認用戶是否與頁面在交互。
HTML5 擴展的 HTMLDocument 屬性:
- readyState :文檔加載情況,值有兩種,加載中(loading)、加載完成(complete)。
- compatMode :渲染模式,值有兩種,標準(CSS1Compat)、混集(BackCompat)。
- head :指向文檔中的<head>元素。
字符集屬性
- chartset :文檔使用的字符集,如 "UTF-8"。
專有擴展
以下屬性方法并未寫入標準,并非所有瀏覽器都支持,使用前請檢測是否存在。
- children:與 childNodes 類似。返回的是一個 HTMLCollection 實例,只包含元素中同樣還是元素的子節點,除此外和 childNodes 無差別。
- contains(node) :檢測 node 元素是否為本元素的后代節點,返回布爾值。注意,以自身作為參數,結果也是 true 。
- innerText :可讀寫。讀模式,由淺入深的順序將子文檔樹的所有文本拼接起來;寫模式,刪除所有子節點,插入指定的文本節點。
Element 類型
Element是非常通用的基類,所有Document對象下的對象都繼承它。以下內容主要針對 HTMLElement類型(HTML文檔)。
特征
- nodeType: Node.ELEMENT_NODE(1)
- nodeName: 元素的標簽名(與 tagName 的值相同)
- nodeValue: null
- parentNode: Document 或 Element
- childNodes:可能是 Element、Text、Comment、ProcessingInstruction、CDATASection、EntityReference 。
標準特性
以下是 HTML 元素都存在的標準特性,屬性值均為可讀寫。標準特性可以作為對象的屬性直接訪問,而自定義特性需要用特定方法獲取/修改。
- id: 元素在文檔的唯一標識符
- title:有關元素的附加說明信息,一般通過工具提示條顯示出來
- lang:元素內容的語言代碼,很少使用
- dir:語言的方向,值為"ltr"(左到右)或"rtl"(右到左),很少使用
- className:元素的 CSS 類名
獲取/操作特性的方法
上面提到標準特性,以下 3 個方法可以訪問對象的所有特性(包括標準與自定義特性)。舉個例,對于<div class="myDiv" my-prop="myProp"></div>來說,class就是標準特性,my-prop就是自定義特性。下面方法的第一個參數為特性名。
- getAttribute() :獲取特性。
- setAttribute() :修改特性,需要第二個參數:新的特性值。若特性不存在,則為其添加新特性并賦值
- removeAttribute() :移除特性。
特殊特性
特殊特性也可以作為對象的屬性直接訪問,但與標準特性有點不同,屬性訪問的值與使用方法getAttribute()得到的值并不一致。
- ?.style:得到一個 CSSStyleDeclaration 對象,該對象包含所有能設置的內聯樣式。更多關于樣式請點擊鏈接。
- .getAttribute('style'):返回style特性的字符串值,如"width: 571px;",未設置任何值則返回null。
- .onclick:得到一個事件處理的 JavaScript 函數,如未指定則返回null。
- .getAttribute('onclick'):返回事件處理函數的字符串值,如未指定則返回null。
- 順帶一說,.click()可以觸發該元素的單擊事件,其他事件同理。
attributes 屬性
attributes 屬性只能被 Element 類型使用,指向 NamedNodeMap 對象,是類似與 NodeList 的"動態"集合,包含該元素的每個特性,每個特性都由一個 Attr 節點表示 (下面介紹) 。
- NamedNodeMap 對象的方法:
- attributes.getNamedItem(name):獲取指定特性節點。
- attributes.setNamedItem(name, value):添加或設置特性節點。
- attributes.removeNamedItem(name):移除指定特性節點。
- attributes.getNamedItem(name):獲取指定特性節點。
- 屬性值訪問:
如,attributes['class'],和attributes.getNamedItem('class')等效。
創建元素
使用document.createElement(tagName)方法創建并返回該新元素,tagName 在 html 文檔中不區分大小寫,然后通過上面的屬性或方法為其添加特性,最后通過appendChild()等方法插入到文檔樹中。
Selectors API Level 2 規范新增的一個方法
matchesSelector():接收一個 CSS 選擇符為參數,返回布爾值,表示是否該選擇符是否與調用元素匹配。如,document.body.matchesSelector('body.page1');? // true。
Element Traversal API 添加的 5 個屬性
一般情況下,使用 childNodes 和 firstChild 等屬性時,獲得的值是包含回車/空格/注釋的節點,例如<div> <span>content</span> </div>中,div對象的 firstChild 是一個空格。為了是篩除掉這種文本/注釋節點,所以有了以下屬性。值得注意的是,除了最后兩個指向同輩元素的屬性,Document 類型的也包含前三個屬性。
- childElementCount :返回子元素(不包括文本節點和注釋)的個數。
- firstElementChild :(非文本和注釋節點的)第一個子元素。
- lastElementChild :(非文本和注釋節點的)最后一個子元素。
- previousElementSibling :(非文本和注釋節點的)前一個同輩元素。
- nextElementSibling :(非文本和注釋節點的)后一個同輩元素。
classList 屬性
由于可以對一個 Element 對象添加多個 className ,但多個 className 卻只是用空格隔開,但我們一般只想修該一個或部分,操作整個 className 字符串顯得比較麻煩。所以有了 classList 屬性,它是新集合類型 DOMTokenList 的實例,同樣是類數組,可以通過方括號語法訪問項。classList 對象包含如下屬性和方法:
- length :該集合的長度,即類名的個數。
- add(<string>) :將給定的字符串添加到列表中,存在則不添加。
- contains(<string>) :判斷集合是否存在給定的值,存在則返回 true ,反之 false 。
- remove(<string>) :從集合中刪除給定的字符串。
- toggle(<string>) :開關,即給定的字符串存在則刪除,否則添加。
自定義數據屬性
HTML5 規定可以為元素添加非標準的屬性,但要添加前綴 "data-",目的是為元素提供與渲染無關的信息,或提供語義信息。
例如,<div id="div1" data-appId="123" data-myname="lisi"><div>。
添加屬性后,可以通過元素的 "dataset" 屬性訪問自定義屬性的值。dataset 屬性指向 DOMStringMap 的實例,就是一個鍵值對的映射。
如上述例子中,可以通過document.getElementById('div1').dataset.appid訪問或改寫(注意,"appid" 會被轉成小寫;若標簽內是"data-app-id",則 JavaScript 訪問其值時,會被轉化成駝峰式,即"appId";JavaScript 獲取其的數據值類型必定是字符串)。)。
插入標記
使用插入標記的技術,可以直接插入 HTML 字符串。以下是 2 個屬性,均為可讀寫,和 1 個方法。需要注意的是,使用這些屬性方法替換子節點可能會導致瀏覽器的內存占用問題,主要是事件綁定和頻繁添加導致,所以建議先手工刪除要被替換的元素的所有事件處理程序和循環添加添加 HTML 標記時應處理好所有的字符串再一次過插入到指定位置。
- innerHTML :讀模式下,返回與調用元素的所有子節點(包括元素、文本和注釋節點)對應的 HTML 標記;寫模式下,則指定相對于的字符串量。注意,通過此屬性插入到 <script>元素并不會執行其中的代碼。不支持此屬性的元素有:<col>、<colgroup>、<frameset>、<head>、<html>、<style>、<table>、<tbody>、<thead>、<tfoot>、<tr>。
- outerHTML :與 innerHTML 類似,此屬性還包含自身元素標簽。例如,某div元素調用 outerHTML ,獲取的是"<div>......</div>"。
- insertAdjacentHTML(location, HtmlText) :此方法用于在指定位置插入 HTML 文本。location 表示要插入的位置,值必須是以下之一(均為小寫):
- "beforebegin":在當前元素之前插入一個緊鄰的同輩元素;
- "afterbegin":在當前元素之下的起始位置插入一個新的子元素;
- "beforeend":在當前元素之下的起始位置插入一個新的子元素;
- "afterend":在當前元素之后插入一個緊鄰的同輩元素。
scrollIntoView() 方法
當容器內容很多,則需要使用滾動條顯示,而此方法是為了更好的控制頁面滾動。元素對象調用此方法時,會使元素出項在最外層的帶滾動條的元素中,下面用"視口元素"指代"最外層的帶滾動條的元素"。可以接收一個布爾值為參數,不傳默認為 true 。
- true :默認值,表示元素頂部盡可能與視口元素頂部平齊。
- false :表示元素底部盡可能與視口元素底部平齊。
專有擴展方法(滾動)
這三個方法都只是在 safari 和 chrome 瀏覽器(可能更多,目前Firefox不支持)部署了。都是與滾動相關。
- scrollIntoViewIfNeeded(isAlignCenter) :當元素已經在視口中,不作任何操作;當元素不在視口中,使滾動窗口滾動到元素可見位置。可傳入一個布爾值,isAlignCenter 表示元素是否垂直居中對其。
- scrollByLines(lineCount) :將元素的內容滾動指定的行高,lineCount 可正可負。
- scrollByPages(pageCount) :將元素的內容滾動到指定的頁面高度,具體的高度有元素的高度決定。
表單元素
表單元素由<form>表示,對應的是HTMLFormElement類型,繼承自HTMLElement。這里不多介紹,請點擊鏈接查看另一篇文章。
Attribute 類型
該類型在討論 Element 類型的 attributes 屬性已有提及。元素的特性在 DOM 中以 Attr 類型表示。盡管他們是節點,但特性去不被認為是 DOM 文檔樹的一部分。一般通過 Elment 類型的方法增刪改查元素的特性。
特征
- nodeType:Node.ATTRIBUTE_NODE(2)
- nodeName:特性的名稱
- nodeValue:? 特性的值。
- parentNode:null
- (在 HTML 中) 沒有子節點
對象的屬性
- name:特性的名稱,與 nodeName 的值一致。
- value:特性的值,與 nodeValue 的值一致。
- specified:是否自定義特性,布爾值。
DocumentFragment 類型
文檔片段,在添加大量 DOM 節點時可作為"倉庫",再一次性添加到文檔中,以減少文檔的回流和重繪。
特征
- nodeType:Node.DOCUMENT_FRAGMENT_NODE(11)
- nodeName: "#document-fragment"
- nodeValue:null
- parentNode:null
- 子節點的種類與 Element 類型一致
創建節點的方法
使用document.createDocumentFragment()可以創建 DocumentFragment 節點,無傳入參數。之后想 Element 類型一樣使用appendChild()方法為其添加子節點,刪除和插入同理。
Text 類型
文本節點由 Text 類型表示,包含的是可以照字面解釋的純文本內容。純文本中可以包含轉移后的 HTML 字符,但不能包含 HTML 代碼。
特征
- nodeType:Node.TEXT_NODE(3)
- nodeName: "#text"
- nodeValue:節點所包含的文本
- parentNode: Element 類型
- 沒有子節點
對象的屬性和方法
- data:該節點的文本內容,可讀寫,與"nodeValue"的值一致。
- appendData(text):添加文本到尾部。
- deleteData(offset, count):刪除從 offset 位置開始的 count 個字符。
- insertData(offset, text):指定位置插入文本。
- replaceData(offset, count, text):替換指定位置的字符串。
- splitText(offset):從 offset 位置將文本節點分成兩個。
- substringData(offset, count):提取指定位置的字符串。
創建節點的方法
使用document.createTextNode(text)方法創建文本節點,"text" 只支持字符串,若文本內容包含 HTML 標簽,只會被當成純字符串解析。
Comment 類型
該類型表示的是注釋節點。與 Text 類型繼承自相同的基類,所以擁有splitText()之外的所有字符串操作方法。
特征
- nodeType:Node.COMMENT_NODE(8)
- nodeName: "#comment"
- nodeValue:注釋的內容
- parentNode: Document 類型 或 Element 類型
- 沒有子節點
創建節點的方法
使用document.createComment(text)可以創建注釋節點,實際生產中很少會用到就不細說。
CDATASection 類型
該類型只針對基于 XML 的文檔,表示的是 CDATA 區域。與 Comment 類型類似,繼承自 Text 類型,所以擁有splitText()之外的所有字符串操作方法。
特征
- nodeType:Node.CDATA_SECTION_NODE(4)
- nodeName: "#cdata-section"
- nodeValue:CDATA 區域中的內容
- parentNode: Document 類型 或 Element 類型
- 沒有子節點
創建節點的方法
使用document.createCDataSection(text)可以創建 CDATASection 節點,傳入節點的內容即可。
DocumentType 類型
包含著與文檔的 doctype 有關的所有信息。對象保存在document.doctype中。
特征
- nodeType:Node.DOCUMENT_TYPE_NODE(10)
- nodeName: doctype 的名稱
- nodeValue:null
- parentNode: Document 類型
- 沒有子節點
對象的屬性
- name:文檔類型的名稱,如<!DOCTYPE HTML>中 name 的值為"HTML"。
關于性能的兩點
轉載于:https://juejin.im/post/5c98cacbf265da60d00048e4
總結
以上是生活随笔為你收集整理的(JS基础)DOM:节点类型的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: C++系列总结——构造与析构
- 下一篇: TriggerMesh开源用于多云环境的