DOM 中文名文檔對象模型,英文名 Document Object Model,我們簡稱為 DOM,是針對 html 和 xml 文檔的一種 API,將 html 以一種樹狀結構呈現出來,可以更直觀去研究文檔結構,我們將這種樹狀文檔結構稱為--DOM 樹,或者節點樹,一樣的概念
一、什麼是 DOM?#
DOM 中文名文檔對象模型,英文名 Document Object Model,我們簡稱為 DOM,是針對 html 和 xml 文檔的一種 API,將 html 以一種樹狀結構呈現出來,可以更直觀去研究文檔結構,我們將這種樹狀文檔結構稱為--DOM 樹,或者節點樹,一樣的概念
js 通過 dom 節點,可以對文檔的 html 標籤,屬性,css 樣式,以及具體的內容做出修改,並對頁面中的所有事件進行響應
二、節點樹#
1. 節點類型#
- 文檔節點--Document
- 標籤節點--Element
- 文本節點--Text
- 註釋節點--Comment
- 屬性節點--Attr
2. 屬性#
- 節點類型--nodeType
- 節點名稱--nodeName
- 節點值--nodeValue
- 子節點--childNodes
- 父節點--parentNodes
- 上一個節點--previousSibling
- 下一個節點--nextSibling
- 第一個子節點--firstChild
- 最後一個子節點--lastChild
3. 文檔節點--document#
(1) 獲取#
- getElementById ()--通過 id 獲取元素
<div id="demo">通過id獲取元素</div>
<script>
var demo = document.getElementById('demo');
demo.onclick = function() {
console.log('通過id獲取元素')
}
</script>
<!-- 點擊id為demo的元素,控制台輸出'通過id獲取元素' -->
- getElementsByName ()--通過 name 獲取元素
<input type="text" name="int" value="通過name獲取元素1">
<input type="text" name="int" value="通過name獲取元素2">
<script>
var int = document.getElementsByName('int');
for(var i = 0;i < int.length; i++) {
console.log(int[i].value);
}
</script>
<!-- 控制台輸出name為int的元素的value值 -->
- getElementsByTagName ()--通過標籤名獲取元素
<div>通過標籤名獲取元素1</div>
<div>通過標籤名獲取元素2</div>
<script>
var div = document.getElementsByTagName('div');
for(var i = 0;i < div.length; i++) {
console.log(div[i].innerHTML)
}
</script>
<!-- 控制台輸出標籤名為div的元素的文本內容 -->
- getElementsByClassName ()--通過 class 獲取元素
<div class="demo">通過class獲取元素1</div>
<div class="demo">通過class獲取元素2</div>
<script>
var demo = document.getElementsByClassName('demo');
for(var i = 0;i < demo.length; i++) {
console.log(demo[i].innerHTML)
}
</script>
<!-- 控制台輸出class為demo的元素的文本內容 -->
- querySelector ()--通過選擇器獲取元素
querySelector () 括號裡面要跟上符號,class就寫.
,id就寫#
,標籤直接寫標籤名TagName
<div>通過選擇器獲取標籤名</div>
<div class="div">通過選擇器獲取class</div>
<div id="div">通過選擇器獲取id</div>
<script>
var divtag = document.querySelector('div');
var divclass = document.querySelector('.div');
var divid = document.querySelector('#div');
divtag.onclick = function() {
console.log('通過選擇器獲取標籤名')
};
// 點擊標籤div,控制台輸出"通過選擇器獲取標籤名"
divclass.onclick = function() {
console.log('通過選擇器獲取class')
};
// 點擊class為div,控制台輸出"通過選擇器獲取class"
divid.onclick = function() {
console.log('通過選擇器獲取id')
};
// 點擊id為div,控制台輸出"通過選擇器獲取id"
</script>
- querySelectorAll ()--通過選擇器獲取元素集合
獲取的是一個數組集合
<input type="text" value="int1">
<input type="text" value="int2">
<input type="text" value="int3">
<script>
var int = document.querySelectorAll('input')
for(i = 0; i < int.length; i++) {
console.log(int[i].value)
}
</script>
<!-- 瀏覽器依次打印出`int1`,`int2`,`int3` -->
(2) 創建#
- createElement ()--創建元素(標籤)節點
<ul id="ul"></ul>
<script>
var ul = document.getElementById('ul');
ul.appendChild(document.createElement('li'))
</script>
可以看到,ul 下面已經生成了一個 li 標籤
- createTextNode ()--創建文本節點
<ul id="ul"></ul>
<script>
var ul = document.getElementById('ul');
var li = ul.appendChild(document.createElement('li'));
var node = document.createTextNode('我是li');
li.appendChild(node);
</script>
li 標籤中生成了一段文本
- createAttribute ()--創建屬性節點
<input type="text">
<script>
var int = document.getElementsByTagName('input')[0];
var value = document.createAttribute('value');
value.nodeValue = '通過創建屬性節點生成';
int.setAttributeNode(value);
</script>
可以看到 value 屬性值被成功創建
- createComment ()--創建註釋節點
<div id="div">創建一個註釋節點</div>
<script>
var div = document.getElementById('div');
var comment = document.createComment('添加一個註釋節點');
div.appendChild(comment);
</script>
f12 查看源碼,可以看到 div 生成一行註釋
- createDocumentFragment ()--創建文檔片段
文檔片段的作用,就相當於添加的所有的節點的父元素
1. 假如沒有 createDocumentFragment,添加了很多節點,也可以在 dom 上呈現,但是每次添加的時候都會調用一次 appendChild () 方法,產生很多次頁面渲染,顯得比較臃腫
2. 把多次添加的節點放在一個 createDocumentFragment 節點裡面,頁面只會調用一次就可以把所有的節點都渲染了
-
createEvent ()--創建事件對象
-
addEventListener ()--添加事件監聽函數
-
removeEventListener ()--移除事件監聽函數
- dispatchEvent ()--觸發事件
操作 css#
<div id="demo">dom</div>
<script>
// 直接通過'.'來操作style
var demo= document.getElementById('demo');
demo.style.color = 'red';
// 通過setAttribute()來創建屬性節點
demo.setAttribute('style','background-color: green');
// 通過style的cssText屬性
demo.style.cssText = "border: 10px solid black";
</script>
4. 元素節點 (element 對象)#
有關 innerHTML, innerText, outerHTML, outerText 的區別
一個是元素內容,一個是文本內容
<div id="div1">第一個div</div>
<div id="div2">第二個div</div>
<div id="div3">第三個div</div>
<div id="div4">第四個div</div>
<div id="div5"></div>
<div id="div6"></div>
<div id="div7"></div>
<div id="div8"></div>
<script>
var div1 = document.getElementById('div1').innerHTML
console.log(div1) // 第一個div
var div1 = document.getElementById('div1').outerHTML
console.log(div1) // <div id="div1">第一個div</div>
var div2 = document.getElementById('div2').innerText
console.log(div2) // 第二個div
var div2 = document.getElementById('div2').outerText
console.log(div2) // 第二個div
document.getElementById('div5').innerHTML = '<a>《第5個div》</a>'
// 在原有的標籤內增加內容,如果有標籤會被識別
document.getElementById('div6').outerHTML = '<a>《第6個div》</a>'
// 原來的標籤會被覆蓋,新的文本中如果含有標籤會自動生成,如果沒有標籤則直接以文本形式展示
document.getElementById('div7').innerText = '<a>《第7個div》</a>'
// 在原有的標籤內增加內容,新標籤不會被識別為標籤元素,而是被當作文本內容直接寫入原標籤內
document.getElementById('div8').outerText = '<a>《第8個div》</a>'
// 原來的標籤會被覆蓋,新標籤不會被識別為標籤元素,而是直接被當作文本形式展示
</script>
(1) 節點屬性#
- childElementCount--返回當前元素的子節點的個數
<div id="demo">
<a></a>
<span></span>
<p></p>
<div></div>
</div>
<script>
var demo = document.getElementById('demo')
console.log(demo.childElementCount) // 4
</script>
- firstElementChild--返回當前元素的第一個子元素節點
lastElementChild--返回當前元素的最後一個子元素節點
<div id="demo">
<a></a>
<span></span>
<p></p>
<div></div>
</div>
<script>
var demo = document.getElementById('demo')
console.log(demo.firstElementChild) // <a></a>
console.log(demo.lastElementChild) // <div></div>
</script>
- nextElementSibling--返回當前元素的下一個兄弟元素節點
previousElementSibling--返回當前元素的上一個兄弟元素節點
<span></span>
<div id="demo"></div>
<p></p>
<script>
var demo = document.getElementById('demo')
console.log(demo.nextElementSibling) // <p></p>
console.log(demo.previousElementSibling) // <span></span>
</script>
- 返回當前元素所有的子節點
<div id="demo">
<span></span>
<p></p>
<a></a>
</div>
<script>
var demo = document.getElementById('demo').children
for(var i in demo) {
console.log(demo[i])
}
</script>
控制台查看返回結果
- 返回所有子節點集合
<div id="demo">
<span></span>
<p></p>
<a id="demo1"></a>
</div>
<script>
var demo = document.getElementById('demo').children
for(var i in demo1.childNodes) {
console.log(demo[i])
}
</script>
(2) 節點方法#
- appendChild--插入子節點
<div id="demo"></div>
<script>
var demo = document.getElementById('demo')
var node = document.createTextNode('插入一個子節點')
demo.appendChild(node)
</script>
f12 可以看到,div 被插入了一個節點
- insertBefore (a, b)--在指定位置插入節點
參數 a 表示要插入的內容,b 表示定位,在 b 節點之前插入 a 節點
<div id="demo"></div>
<script>
var demo = document.getElementById('demo')
var node = document.createTextNode('插入一個子節點')
demo.appendChild(node)
var hr = document.createElement('hr')
demo.insertBefore(hr, node)
</script>
可以看到,原來的文本節點之前,被添加了一個新的元素節點
- replaceChild (a, b)--替換節點
用參數 a 替換參數 b,a 表示新節點,b 表示舊節點
<div id="demo"></div>
<script>
var demo = document.getElementById('demo')
var node = document.createTextNode('插入一個子節點')
demo.appendChild(node)
var h3 = document.createElement('h3')
var h3node = document.createTextNode('title標題')
h3.appendChild(h3node)
demo.replaceChild(h3, node)
</script>
h3
是新節點,node
是舊節點,根據圖片可以看到,b 替換掉了 a,成功上位
- removeChild--父節點刪除子節點
<div id="demo">
<div id="son"></div>
</div>
<script>
var demo = document.getElementById('demo')
var son = document.getElementById('son')
demo.removeChild(son)
</script>
f12 可以看到,id 為 son 的元素節點,通過demo.removeChild()
已經被刪除了
- removeAttribute--刪除屬性節點
<div id="demo" class="div"></div>
<script>
var demo = document.getElementById('demo')
demo.removeAttribute('class')
</script>
class 屬性已經被刪除了
- 刪除文本節點
<div id="demo">文本</div>
<script>
var demo = document.getElementById('demo')
demo.removeChild(demo.childNodes[0])
</script>
通過demo.childNodesp[0]
獲取 demo 的第一個節點,即文本節點,然後removeChild
它,就刪除了
- isEqualNode--判斷兩個元素是否
相等
isSameNode--判斷兩個元素是否相同
兩者分別代表
相等
和相同
(1) isEqualNode
相等,指的是兩個節點是否是同一類型,具有相等的屬性(包括:nodeName, nodeValue... 等等),還有相等的 attributes,childNodes(相等的位置包含相同的值)
(2) isSameNode
相同,指的是兩個節點引用的是同一個對象
<form action="#">
<input type="button" />
</form>
<form action="#">
<input type="button" />
</form>
<form action="#" id="o">
<input type="button" />
</form>
<form action="#" id="o">
<input type="text" />
</form>
<script>
var forms = document.forms;
var form1 = forms[0];
var form2 = forms[1];
var form3 = forms[2];
var form4 = forms[3];
var _form1 = document.querySelectorAll('form')[0];
console.log(form1.isSameNode(form1)) //true 兩個節點引用的對象都是第一個form
console.log(form1.isSameNode(_form1)) //true 兩個節點引用的對象都是第一個form
console.log(form1.isSameNode(form2)) //false 兩個節點引用的不是一個對象
console.log(form1.isEqualNode(form2)) //true 兩個節點具有完全等同屬性
console.log(form1.isEqualNode(form3)) //false form1中無等同的id屬性
console.log(form3.isEqualNode(form4)) //fasle form4的childNodes中的input為text類別,與form3不同
</script>
根據例子代碼可以看出區別:
(1) isSameNode
只有引用同一個對象時才相同,比如用兩中方法調用同一個對象,再比較這兩種方法,比來比去還是那個對象,所以相同
(2) 而isEqualNode
比較兩個對象的元素節點是否相等,只要兩者一致就可以相等 true
- hasChildNodes ()--判斷一個元素是否擁有子節點
判斷demo
是否擁有子節點,然後輸出他的子節點
<div id="demo">
<!-- <a></a> -->
</div>
<script>
var demo = document.getElementById('demo')
console.log(demo.hasChildNodes())
console.log(demo.childNodes)
</script>
- contains (a)--判斷一個節點是否包含指定子節點(參數 a 表示要判斷的子節點)
存在id="a"
的元素,因此 contains 判斷成功輸出true
,
不存在id="b"
的元素,因此輸出false
<div id="demo">
<a id="a"></a>
<a></a>
</div>
<script>
var demo = document.getElementById('demo')
var a = document.getElementById('a')
console.log(demo.contains(a)) // true
var b = document.getElementById('b')
console.log(demo.contains(b)) // false
</script>
5. 屬性節點 (Attr 對象)#
<input type="text" id="int">
<script>
var int = document.getElementById('int')
// 1.獲取屬性值
console.log(int.getAttribute("type"))
// text
// 2.獲取屬性節點
console.log(int.getAttributeNode("type"))
// type="text"
// 3.設置屬性值
int.setAttribute("value", "input框")
// <input type="text" id="int" value="input框">
// 4.設置屬性節點
let name = document.createAttribute("name");
name.nodeValue = "uname";
int.setAttributeNode(name);
console.log(int.getAttributeNode('name').value)
// <input type="text" id="int" value="input框" name="uname">
// 5.刪除屬性節點
console.log(int.removeAttribute('name'))
// <input type="text" id="int" value="input框">
// 6.判斷是否存在屬性
console.log(int.hasAttributes())
// true
// 7.判斷是否存在指定屬性
console.log(int.hasAttribute('value'))
// true
</script>
注意:
hasAttribute
和hasAttributes
的區別
hasAttributes
判斷是否存在屬性,
hasAttribute
判斷是否存在指定屬性