DOM
- 基本概念
- 節點類型
- 節點樣式
- 事件
1 基本概念
Document Object Model 文檔對象模型
BOM:與瀏覽器交互的方法和接口
DOM:處理網頁內容的方法和接口 - HTML和XML的應用程序接口
window是BOM的核心對象,window上的document是DOM的核心
任何HTML或XML文檔都可以用DOM表示為一個由節點構成的層級結構
使用HTML Tree Generator擴展程序可以查看任意網頁的DOM結構
-
Document
-
Element html
-
Element head
- Element title
-
Element body
- Text Hello World!
-
document為根節點類型為Document
根節點有一個唯一子節點html,我們稱之為文檔元素documentElement,類型為Elementconsole.log(document); console.log(document.documentElement);可以看到document返回的是完整的文檔,documentElement只是html節點
-
2 節點類型
總共12種,這裏僅部分介紹
- Node
- Document
- Element
- Text
- Comment
- CDATASection
- DocumentType
- DocumentFragment
- Attr
2.1 Node類型
所有節點類型都繼承Node類型,所以所有節點類型都共享相同的基本屬性與方法
console.dir(Document)
console.dir(Text);
console.dir(DocumentFragment);
其他節點類型都對Node類型進行了引用
2.1.1 Node類型的屬性
節點類型 靜態屬性
- Node.DOCUMENT_NODE:9
- Node.ELEMENT_NODE:
1 - Node.TEXT_NODE:
3 - Node.COMMENT_NODE:8
- Node.CDATA_TYPE_NODE:4
- Node.DOCUMENT_TYPE_NODE:10
- Node.DOCUMENT_FRAGMENT_NODE:11
- Node.ATTRIBUTE_NODE:2
節點信息
- baseURL:節點絕對基址,等價於location.href
- isConnected:是否與DOM樹連接
- nodeName:當前節點名稱
-
nodeValue:返回或
設置當前節點的值默認情況下,文檔節點返回
null,對於text,comment,CDATA返回文本內容,對於attribute返回該屬性的屬性值 -
nodeType:按上述對應關係返回節點類型的數值
console.log(document.nodeType);//9 console.log(document.documentElement.nodeType);//1 - ownerDocument:返回當前節點的頂層document對象
-
textContent:返回當前節點以及
所有子節點的文本內容包括script標籤這種頁面內不可見的腳本document與DOCTYPE類型返回
null
節點關係
- childNodes:返回子節點的類數組對象NodeList,該對象會
及時更新 - firstChild:第一個子節點
- lastChild:最後一個子節點
- previousSibling:前一個兄弟節點
- nextSibling:後一個兄弟節點
- parentNode:返回父節點
- parentElement:返回父元素,nodeType不為
1時返回null
2.1.2 Node類型上的方法
操作節點
- appendChild(child):將一個節點附加到父節點的子節點列表的末尾,若父節點
已存在直接將該節點移動至末尾 -
insertBefore(newNode,referenceNode):指定位置插入至某節點之前,若已經存在則只
移動不添加const div = document.createElement('div') div.textContent = '123' const html = document.documentElement html.insertBefore(div, html.childNodes[1]) console.log(document); - cloneNode(deep):克隆一個節點副本,deep為true時,子節點同時被克隆
- replaceNode(newChild,oldChild):替換當前節點的一個子節點,返回被替換的節點
- removeChild(child):刪除當前節點的一個子節點,返回該節點
- normalize():節點
規範化,刪除空文本節點,相鄰文本節點合併
節點信息
- hasChildNodes():當前節點是否
有子節點 - contains(otherNode):節點參數是否是該節點的子節點,是否
包含 - isEqualNode(otherNode):兩個節點是否相等
-
compareDocumentPosition(otherNode):參數節點與該節點的位置關係
返回值:1 - 不在同一文檔,2 - 之前,4 - 之後,8 - 包含,16 - 被包含 ,32 -待定。這些值會累加,當otherNode被包含時為16+4=20
- getRootNode(options):返回上下文的根節點
命名空間
- lookupNamespaceURI():返回當前節點與指定命名空間前綴綁定的命名空間URI,對動態指定的命名空間不起作用
- lookupPrefix():同上
- isDefaultNamespace(URI):是否為默認命名空間
2.2 Document類型
瀏覽器中的document對象是HTMLDocument的實例,HTMLDocument又繼承了Document,document可以使用Document類型上的屬性與方法
2.2.1 Document上的屬性
- body:取得對<body></body>的引用
- doctype:取得對<!doctype>的引用
- head:對head的引用
文檔信息
- title:讀取或修改瀏覽器標題,不會修改title元素
-
cookie:返回一個使用分號分隔的cookie列表,可寫入
連續的賦值不會覆蓋,而是相當於添加的操作,過期時間添加expires=到期時間
- readyState:文檔加載狀態
- lastModified:文檔最後修改時間
- scripts:返回所有script元素
- images:返回文檔圖片列表
- links:返回文檔中所有超鏈接列表
- forms:返回所有便當元素
- plugins:返回插件列表
- activeElement:返回獲得焦點的元素
- charaterSet:返回當前文檔的字符編碼
- compatMode:表明當前文檔模式是怪異模式還是標準模式
- designMode:on|off,控制文檔是否可編輯
節點信息
- children:相較於childNodes,它不包括文本節點與註釋
- childElementCount:相當於children.length
- firstElementChild:第一個元素節點
- lastElementChild:最後一個元素節點
- previousElementSibling
- nextElementSibling
2.2.2 Document上的方法
與Node對比
-
adoptNode(externalNode):從其他文檔剪切一個節點導入當前文檔
可用於對iframe的操作
- imporNode(externalNode,deep):從其他文檔拷貝一個節點導入當前文檔,deep是否拷貝子節點
- append(...Node|DOMString):相較於appendChild,它支持多個參數並且可以傳入字符串作為Text類型節點
- prepend(...):開始位置插入
- replaceChildren(...):將原文檔集合替換為一個新的文檔集合
文檔寫入
- open():打開一個文檔
- write('html'):寫入內容
- write('html'):寫入內容並換行
- close():關閉文檔
創建節點
- createElement(tagName):返回新建的元素
- createElementNS(namespaceURI,qualifiedName):返回指定命名空間URI和限定名稱的元素
- createTextNode(data):返回一個文本節點
- createComment(data):返回一個註釋節點
- createCDATASection(data):返回一個CDATA片段節點
-
createDocumentFragment():返回一個空白文檔片段
DocumentFragments是DOM節點但不是DOM樹的一部分,文檔片段存於
內存中,將子節點插入到文檔片段是不會引起頁面迴流,性能佳 - createAttribute(name):返回一個Attr節點,設置該節點的value屬性可設置屬性值
獲取節點
- getElementById(id):指定id的節點
- getElementsByClassName(class):指定類名的節點
NodeList - getElementsByName(name):指定name的節點
NodeList - getElementsByTagName(tag):指定標籤名
- getElementsByTagName(namespace,tag):指定命名空間下的標籤集合
- querySelector(selectors):返回指定一組CSS選擇器匹配的第一個元素
- querySelectorAll(selectors):返回一個靜態的NodeList,採用深度優先遍歷
2.3 Element類型
表示XML或HTML元素,對外暴露出訪問元素標籤名、子節點和屬性的能力
2.3.1 Element上的屬性
節點信息
- attributes:返回該元素所有屬性節點的實時集合
- id:節點屬性
- className:class屬性值
- tagName:標籤名 - 大寫
元素尺寸
- clientHeight/Width:content + padding
- offsetHeight/Width:border + client
- scrollHeight/Width:無滾動條時,元素內容大小,與client相同,不計算邊框
元素位置
- clientLeft/Top:邊框寬度
- offsetLeft/Top:元素邊框到offsetParent邊框的距離
-
scrollLeft/Top:滾動的距離
常對documentElement使用
元素內容
- innerHTML:與textContent相比,它不能發揮隱藏的文本,會觸發迴流,寫入文本時
避免使用 - outerHTML:innerHTML + 本元素,可以連同自己一塊處理
2.3.2 Element上的一些方法
操作節點
- after(...nodes):在其父元素子節點列表中插入節點
- before(...nodes)
- append(...nodes)
- perpend(...nodes)
- remove():從所屬DOM樹中刪除
獲取屬性
- hasAttribute(name):是否有某個屬性
- hasAttributeNS(namespace,name):該元素是否包含指定的元素
- getAttribute(name):返回元素屬性值
- getAttributeNames():返回元素屬性名稱的
數組 - getAttributeNode(name):返回指定元素的指定屬性節點
- getAttributeNodeNS(namespace,name):通過命名空間URI和名稱來獲取屬性節點
屬性操作
- setAttribute(name,value):有則更新,無則添加
- removeAttribute(name):刪除一個屬性
- setAttributeNode(attr)
- removeAttributeNode(attrNode)
2.4 Text類型
- appendData(text):尾部添加文本
- deleteData(offset,count):從位置offset開始刪除count個字符
- replaceData(offset,count,text):用text替換從位置offset到offset+count的文本
- insetData(offset,text):從offset開始插入文本
- splitText(offset):在位置offset拆分為兩個文本節點
- substringData(offset,count):提取從offset到offset+count的文本
3 元素樣式
document.style.attr:讀取與設置元素的樣式
3.1 style上的方法
- getPropertyValue(name):返回屬性值
- getPropertyPriority(name):檢測是否使用了important
- removeProperty(name)
- setProperty(name,value,priority)
3.2 計算樣式
- getComputedStyle(elem,pseudoElt):返回頁面展示的元素最終的樣式對象
-
currentStyle.attr:當前樣式IE
在做運動處理時,會經常使用offset,但是它不僅僅只有寬高,計算移動時容易出現反方向的bug,計算樣式可以解決這個問題
4 事件
DOM事件流
- 捕獲階段:從根節點開始查找
- 到達目標:尋找到目標元素的目標事件
- 冒泡階段:從目標元素向上傳遞
- 事件綁定
- DOM事件對象
- 事件類型
4.1 事件綁定
const oBtn = document.getElementsByTagName('button')
function handle() {
console.log('事件1');
}
oBtn[0].addEventListener('click', handle)
oBtn[1].onclick = () => {
console.log('事件2');
oBtn[0].removeEventListener('click', handle)
console.log('解綁事件1');
}
如果需要解綁,不能使用匿名函數
4.2 DOM事件對象
event對象是傳給事件處理程序的唯一參數
event的屬性
- bubbles:是否冒泡
- cancelable:是否可取消事件默認行為
- currentTarget:當前元素
- defaultPrevented:是否調用了對應的方法
- eventPhase:事件處理的階段1 2 3
- type:事件類型
- target:事件目標
event的方法
- preventDefault():阻止默認行為
- stopPropagation() :取消所有後續事件捕獲或事件冒泡
- stopImmediatePropagation():取消所有後續事件捕獲或事件冒泡,並阻止調用任何後續事件處理程序
this始終指向currentTarget,target才是事件目標
4.3 事件類型
- 用户界面事件
- 焦點
- 鼠標
- 滾輪
- 輸入
- 鍵盤
- 合成:在某種IME輸入字符時觸發
事件處理程序