扒一扒DOM

目錄
1.什么是DOM
2.節點的概念
3.節點的屬性和方法
4.Element對象的屬性和方法
5.Attribute對象的屬性和方法

1.什么是DOM

DOM(Document Object Model),即文檔對象模型,是HTML和XML文檔的編程接口

  • 瀏覽器的渲染引擎將結構化文檔,如HTML文檔解析成一系列的節點(Document對象,即Node)
  • 將一系列節點組成DOM Tree
  • 瀏覽器原生提供一個Node對象,所有類型的節點(節點可細分,詳見下面)都是由Node對象派生出來,都繼承Node的屬性和方法,即每一個節點都提供規范的對外編程接口,如對于Element節點,Node對象提供getElementById()的方法(這就是編程接口)去獲取元素節點,從而可以對元素節點進行編程
  • DOM Tree

![](http://upload-images.jianshu.io/upload_images/1993435-612343ae9cb6ac27.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

2.節點的概念

文檔解析成DOM Tree后,DOM Tree是由各個不同類型的節點組成的

  • 節點的類型
    節點主要有以下六種類型:
節點類型 節點含義
Document 整個文檔(window.document)
DocumentType 文檔的類型(<DOCTYPE html>)
Element HTML元素(<body>)
Attribute HTML元素的屬性(id="nav")
Text 文本內容
DocumentFragment 文檔的片段
  • 節點間的關系
    節點樹中的節點彼此擁有層級關系,可分為父(parent)、子(child)和同胞(sibling)三種節點

【注】

  • 在節點樹中,頂端節點被稱為根(root)

  • <!DOCTYPE html>不算是根節點

  • API(應用編程接口)
    DOM規范文檔的標準(將文檔解析為各個節點對象)和提供相應的API(Node節點的屬性和方法)

    • Node的屬性:關于Node對象在值方面的規定,如:

    • Node的方法:關于Node對象在操作方面的實現

3.Node的屬性和方法

  • Node屬性
    • nodeName和nodeType
節點類型 nodeName nodeType
DOCUMENT_NODE #document 9
ELEMENT_NODE 大寫的HTML元素名 1
ATTRIBUTE_NODE 同Attr.name 2
TEXT_NODE #text 3
DOCUMENT_FRAGMENT_NODE #document-fragment 11
DOCUMENT_TYPE_NODE 同DocumentType.name 10

【注】
對于nodeName而言:文檔節點、文本節點和文檔碎片節點返回統一的#document、#text和#document-fragment,其他節點根據實際情況返回特定值

  • 關系屬性
    parentNode/parentElement/childNodes/firstChild/lastChild/nexSibling/previousSibling
    【還包括】
    firstElementChild/lastElementChild/childElementCount

  • 文本內容屬性
    innerText/texContent

示例代碼:

<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <title>JS Bin</title>
</head>
<body>
<div id="box">
  <ul id="wrapper">
    <li id="ct1">1</li>
    1<li id="ct2">2</li>
    2<li id="ct3">3</li>
    <li id="ct4">4</li>
    <li id="ct5">5</li>
  </ul>
</div>
</body>
</html>

function print(ele){
  console.log(ele)
}
print(document.getElementById('box').nodeName)
print(document.getElementById('box').nodeType)
print(document.getElementById('wrapper').parentNode)
print(document.getElementById('wrapper').parentElement)
print(document.getElementById('wrapper').childNodes)
print(document.getElementById('wrapper').firstChild)
print(document.getElementById('wrapper').lastChild)
print(document.getElementById('ct2').nextSibling)
print(document.getElementById('ct2').previousSibling)
print(document.getElementById('ct2').textContent)
print(document.getElementById('ct3').innerText)
  • Node方法
    • hasChildNodes() && contains() && isEqualNode()
print(document.getElementById('wrapper').hasChildNodes())//true
//
var wrapper = document.getElementById('wrapper')
var ct1 = document.getElementById('ct1')
document.write(wrapper.contains(ct1))
//
var ct2 = document.getElementById('ct2')
var ct3 = document.getElementById('ct3')
document.write(ct2.isEqualNode(ct3))
var p = document.createElement('p');
var text = document.createTextNode('hello world')
p.appendChild(text)
document.getElementById('wrapper').appendChild(p)
  • cloneNode()
var ct1 = document.getElementById('ct1')
var ct1Cp = ct1.cloneNode(true)
document.body.appendChild(ct1Cp)
  • insertBefore()
var p = document.createElement('p');
var text = document.createTextNode('hello world')
p.appendChild(text)
document.getElementById('wrapper').insertBefore(p,ct1)
  • removeChild() & replaceChild()
var p = document.createElement('p');
var text = document.createTextNode('hello world')
p.appendChild(text)
var div = document.createElement('div')
var text = document.createTextNode('lord of this ring')
div.appendChild(text)
document.getElementById('wrapper').insertBefore(p,ct1)
var ct4 = document.getElementById('ct4');
document.getElementById('wrapper').removeChild(ct4)
var ct5=document.getElementById('ct5')
document.getElementById('wrapper').replaceChild(div,ct5)
  • NodeList && HTMLCollection
    節點對象都是單個節點,如果需要將多個節點放在同一個集合中,則用到NodeList接口和HTML Collection接口

Node.childNodes和document.querySelectorAll()都是NodeList接口,返回的都是包含各個節點的集合的對象(偽數組),NodeList接口有時返回動態集合有時是靜態集合

部署NodeList接口的對象的屬性和方法:

var wrapper = document.getElementById('wrapper')
var nodeList = wrapper.childNodes
//node.childNodes返回所有子節點組成的偽數組
print(nodeList)
//nodeList接口提供length屬性
print(nodeList.length)
//訪問偽數組元素的方法可以使用偽數組下標或是nodeList.item()方法
//對部署nodeList接口的對象進行遍歷時,應該避免使用for in,因為這種方法會把length和item方法也遍歷進去,而且不保證成員的遍歷順序
for(var i=0;i< nodeList.length;i++){
print(nodeList[i])
}
print(nodeList.item(4))
//動態集合的表現:添加對象的元素,會立即反映到nodeList接口
wrapper.appendChild(document.createElement('div'))
print(nodeList.length)
print(document.querySelectorAll('li'))
node.querySelectorAll()返回的是一個靜態集合

部署HTMLCollection接口的對象的屬性和方法
部署HTMLCollection接口的對象的集合成員都是Element節點,并且該接口都是動態集合

4.Element對象的屬性和方法

示例代碼

<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <title>JS Bin</title>
</head>
  <style>
  .nav{
  background: #ccc;
}
.content{

  width:100px;
  height:100px;
}
  </style>
<body>
<div id="box">
  <ul id="wrapper" class="content" style="color:red">
    <li id="ct1">1</li>
    1<li id="ct2">2</li>
    2<li id="ct3">3</li>
    <li id="ct4">4</li>
    <li id="ct5">5</li>
  </ul>
</div>
</body>
</html>
  • innerHTML
var wrapper = document.getElementById('wrapper')
print(wrapper.innerHTML)
  • 獲取Element對象的方法
    getElementById()
    getElementBtTagName():以 NodeList 對象形式返回具有指定標簽名的元素子元素集合,通常使用document.getElementByTagName('TagName')[0]去獲取該標簽下的子元素
    document.getElementByClassName()
var wrapper = document.getElementById('wrapper')
var ul = document.getElementsByTagName('ul')[0]
//返回包含2個元素的數組,前面是
var style = document.getElementsByClassName('content')[0]
var list = document.querySelector('li')
var list2 = document.querySelectorAll('li')
print(wrapper)
print(ul)
print(style)
print(list)
print(list2)
  • 元素對象的屬性的相關方法
    getAttribute()/setAttribute()/removeAttribute()
function print(ele){
  console.log( ele)
}
var wrapper = document.getElementById('wrapper')
print(wrapper.getAttribute('class'))
wrapper.setAttribute('class','nav')
wrapper.removeAttribute('style')

5.Attribute對象的屬性和方法

  • node.attributes/node.attributes[index].name
var ul = document.getElementsByTagName('ul')[0].attributes
var ul_id = document.getElementsByTagName('ul')[0].attributes[0].name
var ul_class = document.getElementsByTagName('ul')[0].attributes[1].name
var ul_style = document.getElementsByTagName('ul')[0].attributes[2].name
print(ul)
print(ul_id)
print(ul_class)
print(ul_style)
  • Element的樣式
//css
.f-size{font-size: 30px;}
//js
var wrapper = document.getElementById('wrapper')
wrapper.style = "background-color:#ccc" 
wrapper.style.border = "1px solid" 
wrapper.style['border-radius'] = '5px'
wrapper.className = 'f-size'
//盡量不要使用style方法添加屬性,而是通過添加類的方法去改變樣式

var wrapper = document.getElementById('wrapper')
print(wrapper.id)
print(wrapper.className)
print(wrapper.style)
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容