關于dom操作,我們分創建、增、刪、改、查、屬性操作、事件操作來大體介紹一下
創建
1.createElement:通過傳入標簽來創建一個dom
demo
var node=document.createElement('div')
node.innerHTML='我是新增的node'
document.body.appendChild(node)
2.createTextNode:用來創建一個文本節點
demo
var node=document.createTextNode('我是新增的文本節點')
document.body.appendChild(node)
3.cloneNode:克隆一個節點,有一個參數,true支持深度克隆,false不支持深度克隆
demo
<div id="div1">我是一個dom
<span>我是一個子節點</span>
</div>
<script type="text/javascript">
var cn = document.querySelector('#div1').cloneNode()
var cn2 = document.querySelector('#div1').cloneNode(true)
console.log(cn)
console.log(cn2)
</script>
淺拷貝的結果為
<div id="div1"></div>
深拷貝的結果為
<div id="div1">我是一個dom
<span>我是一個子節點</span>
</div>
4. createDocumentFragment: 用來插入一段dom
這個方法的運用,可以減少頁面的重繪與回流問題,能批量的插入dom
demo
var temp = document.createDocumentFragment()
var a = document.createElement('div')
a.innerHTML = 'It\'s a'
var b = document.createElement('span')
b.innerHTML = 'It\'s b'
temp.appendChild(a)
temp.appendChild(b)
document.body.appendChild(temp)
添加到body之前,都沒有真正的加入到dom tree里面,避免了重繪與回流
增
1.appendChild
A.appendChild(B):將B添加到A子元素的最后一個位置,如下
默認的dom結構
<div id="parent">
<span>我是一開始就有的子節點</span>
</div>
執行以下的js之后
var parent = document.querySelector('#parent')
var child = document.createElement('div')
child.innerHTML = '我是子節點'
parent.appendChild(child)
<div id="parent">
<span>我是一開始就有的子節點</span>
<div>我是子節點</div>
</div>
2.insertBefore
parent.insertBefore(newNode, exitsNode):將newNode添加到exitsNode的前面
默認dom結構
<div id="me">
<div>child</div>
<div>child2</div>
<div>child3</div>
<div>child4</div>
<div>child5</div>
<div>child6</div>
<div>child7</div>
</div>
<input type="number">
<button>新增一個孩子</button>
執行以下的js代碼,填入一個數字,點擊按鈕之后
function addNode() {
var index = document.querySelector('input').value
var tempDom = document.createElement('div')
tempDom.innerText = '我是新增的孩子'
var me = document.querySelector('#me')
var children = me.querySelectorAll('div')
me.insertBefore(tempDom, children[index])
}
document.querySelector('button').addEventListener('click', addNode)
<div id="me">
<div>child</div>
<div>child2</div>
<div>child3</div>
<div>我是新增的孩子</div>
<div>child4</div>
<div>child5</div>
<div>child6</div>
<div>child7</div>
</div>
注:如果第二個參數不存在或者異常,則會插入到最后
3.insertAdjacentElement
它包括兩個參數,其中第二個參數是要加的子節點,核心在于第一個參數,有如下的取值
beforebegin:把第二個參數加到當前節點的前面
afterend:把第二個參數加到當前節點的后面
afterbegin:把第二個參數加到當前節點的第一個子節點位置
beforeend:把第二個參數加到當前節點的最后一個節點的位置
一開始我看到這個也是懵逼的,其實記這個可以掌握一定的技巧,以beforebegin,和afterbegin來記,首先,begin肯定是在前面,before肯定也是在前面,就是兩個前面,就在節點前加,我就不類推了
刪
1.removeChild
parent.removeChild(child),刪除parent下的child節點,并且返回這個節點
dom結構如下
<div id="deleteDemo">
<div>第一個子節點</div>
<div>第二個子節點</div>
<div>第三個子節點</div>
<div>第四個子節點</div>
</div>
<input type="number" id="txtDeleteIndex" />
<button id="btnDelete">刪除一個孩子</button>
執行以下的js代碼,輸入一個數字,并點擊按鈕
function deleteNode() {
var index = document.querySelector('#txtDeleteIndex').value
var deleteDemo = document.querySelector('#deleteDemo')
var children = deleteDemo.querySelectorAll('div')
var removeChild = children[index] && deleteDemo.removeChild(children[index])
console.log(removeChild)
}
document.querySelector('#btnDelete').addEventListener('click', deleteNode)
<div id="deleteDemo">
<div>第一個子節點</div>
<div>第三個子節點</div>
<div>第四個子節點</div>
</div>
2.replaceChild
parent.replaceChild(newNode,oldNode),將oldNode替換為newNode
dom如下
<div id="replaceNodeDemo">
<div>第一個子節點</div>
<div>第二個子節點</div>
<div>第三個子節點</div>
<div>第四個子節點</div>
</div>
<input type="number" id="txtReplaceIndex" />
<button id="btnReplace">替換一個孩子</button>
執行以下的js代碼,輸入一個數字,并點擊按鈕
function replaceNode() {
var index = document.querySelector('#txtReplaceIndex').value
var replaceNodeDemo = document.querySelector('#replaceNodeDemo')
var children = replaceNodeDemo.querySelectorAll('div')
var newNode = document.createElement('div')
newNode.innerHTML = '我是替換之后的節點'
var replaceChild = children[index] && replaceNodeDemo.replaceChild(newNode, children[index])
console.log(replaceChild)
}
document.querySelector('#btnReplace').addEventListener('click', replaceNode)
<div id="replaceNodeDemo">
<div>第一個子節點</div>
<div>第二個子節點</div>
<div>我是替換之后的節點</div>
<div>第四個子節點</div>
</div>
改
修改dom,一般是修改dom的屬性,dom的html, text, 表單的值等
1.setAttribute
A.setAttribute(property, value):設置屬性property的值為value
代碼
<div id="divSetAttribute"></div>
<label for="txtProperty">屬性:</label>
<input id="txtProperty" />
<br />
<label for="txtValue">屬性值:</label>
<input id="txtValue" />
<button id="btnProperty">設置屬性</button>
<script type="text/javascript">
var divSetAttribute = document.querySelector('#divSetAttribute')
var txtProperty = document.querySelector('#txtProperty')
var txtValue = document.querySelector('#txtValue')
var btnProperty = document.querySelector('#btnProperty')
function setAttribute() {
divSetAttribute.setAttribute(txtProperty.value, txtValue.value)
}
btnProperty.addEventListener('click', setAttribute)
</script>
2.innerHTML:獲取或者設置dom的dom內容
dom結構如下
<div id="parent">
<div>第一個子節點</div>
<div>第二個子節點</div>
<div>第三個子節點</div>
<div>第四個子節點</div>
</div>
獲取parent的innerHTML,結果為
<div>第一個子節點</div>
<div>第二個子節點</div>
<div>第三個子節點</div>
<div>第四個子節點</div>
3.innerText:獲取或者設置dom的文本內容
dom結構如下
<div id="parent">
<div>第一個子節點</div>
<div>第二個子節點</div>
<div>第三個子節點</div>
<div>第四個子節點</div>
</div>
獲取parent的innerText,結果為
第一個子節點
第二個子節點
第三個子節點
第四個子節點
注意與innerHTML的區別
4.value:獲取或者設置input, select的value
<select id="s1">
<option value="2">中國</option>
<option selected="true" value=3>日本</option>
<option value="4">韓國</option>
</select>
<script>
document.querySelector('#s1').querySelectorAll('option')[document.querySelector('#s1').selectedIndex].value
</script>
查
查詢dom,這一塊的api比較豐富,可能會有遺漏
1.document.getElementById(id):古老的方法,根據id獲取元素,不推薦
2.document.getElementsByTagName(tagName):古老的方法,根據dom的類型獲取元素,不推薦
3.document.getElementsByClassName(className):古老的方法,根據className獲取元素,不推薦
document.getElementsByName(name):古老的方法,根據name獲取元素,不推薦
4.document.getElementsByTagNameNS():沒用過
----------------------------------------------分割線----------------------------------------------
接下來,要重點介紹幾個目前常用的api
1.document.querySelector(css選擇器):根據css選擇器來獲取dom,如果有多個,返回第一個
dom
<div class="test">1</div>
<div class="test">2</div>
<div class="test">3</div>
執行以下代碼
document.querySelector('.test')
返回
<div class="test">1</div>
2.document.querySelectorAll(css選擇器):返回所有滿足條件的元素
以上面的例子為例,如果使用querySelectorAll,那么返回值就是三個元素,這兩個api比較相似,只是一個返回一個dom,一個返回多個dom,不展開了
3.獲取子節點children
dom代碼
<div id="div1">
It's me
<span>child</span>
<div>
child2
<p>leaf</p>
</div>
</div>
執行以下代碼之后
document.querySelector('#div1').children
得到了兩個節點,分別是
<span>child</span>
和
<div>
child2
<p>leaf</p>
</div>
由此可見,children獲取的是dom元素
4.獲取所有子節點childNodes
還是上面的dom結構,來執行以下以下代碼
document.querySelector('#div1').childNodes
返回了五個元素
nodes[0] =It's me
nodes[1] =<span>child</span>
nodes[2] =換行符
nodes[3] =<div>
child2
<p>leaf</p>
</div>
nodes[4] =換行符
很明顯,它不僅返回了dom子元素,還返回了文本子元素
5.獲取父節點parentNode和parentElement
兩者大體差不多,區別和children和childNodes類似,不贅述了
6.獲取兄弟節點previousSibling、previousElementSibling、nextSibling、nextElementSibling
推薦使用帶Element的,大多數情況下,好像都不需要文本節點
7.獲取首尾節點firstChild、firstElementChild、lastChild、lastElementChild
區別參考上一條
8.getComputedStyle
該方法是window下的一個方法,用來計算一個dom元素生成好之后的style,很全,不過因為chrome下的調試很方便,很少用到這個方法
9.getBoundingClientRect
這個方法我經常用到,在以前的博文中也有提到,它是用來獲取邊距的,很有用
屬性操作
1.setAttribute:設置dom的屬性
A.setAttribute(name,value),上面有提到,不贅述
2.getAttribute:得到dom的屬性
A.getAttribute('id') 獲取dom A的屬性id
3.removeAttribute移除屬性
A.removeAttribute(id) 移除id屬性
事件
1.添加事件:事件的添加,一般三種方式,直接綁定dom,通過js賦值,通過addEventListener
代碼
<div id="div1" onclick="alert(1)">
我是用來測試的
</div>
<script type="text/javascript">
var div1 = document.querySelector('#div1')
div1.onclick = function() {
alert(2)
}
div1.addEventListener('click', function() {
alert(3)
})
</script>
以上代碼分別通過三種方式綁定了事件,點擊的結果是,彈出了2和3,并沒有彈出1,這是因為,當js中直接給onclick賦值時,把直接綁定在dom上的事件覆蓋了,假如下面還有一個onclick的賦值,那么它也會覆蓋alert(2),但是add這種方式并不會覆蓋,而是會追加,我們再把代碼修改一下驗證
<div id="div1" onclick="alert(1)">
我是用來測試的
</div>
<script type="text/javascript">
var div1 = document.querySelector('#div1')
div1.onclick = function() {
alert(2)
}
div1.onclick = function() {
alert('2和3之間')
}
div1.addEventListener('click', function() {
alert(3)
})
div1.addEventListener('click', function() {
alert(4)
})
</script>
修改之后,彈出的結果是‘2和3之間’,3,4,由此可見,以上結論正確
2.移除事件
對于直接綁定在dom上的事件,可以采用removeAttribute來移除
對于賦值on這種的,可以重新賦值為null
對于add的,這種稍微復雜一點,此時首先在add時,不能直接綁定匿名方法 了,要定義一個具名的方法,移除時也要綁定上此方法,代碼如下
<div id="div1">
我是用來測試的
</div>
<script type="text/javascript">
var div1=document.querySelector('#div1')
function Test(){
alert(133)
div1.removeEventListener('click',Test)
}
div1.addEventListener('click',Test)
</script>
以上點擊事件,只會執行一次