前端開發始終繞不過的就是操作DOM,在以前,我們使用Jquery,zepto等庫來操作DOM,之後在vue,Angular,React等框架出現後,我們通過運算元據來控制DOM(絕大多數時候),越來越少的去直接操作DOM,更不用說用原生的JS來操作DOM了。
但是並不是所有時候都一定要引入這些庫,對於基礎的JS操作DOM的一些方法,還是要有些瞭解的。這裡就算是回顧一下JS那些熟悉卻也陌生的DOM操作函式。
查詢
按照ID查詢
document.getElementById(id) // 相容最好
// demo
// HTMl
<body>
<div id="main">
<div id="content"></div>
</div>
</body>
// Script
const mainDom = document.getElementById('main');
const contentDom = document.getElementById('content');
複製程式碼
按照class查詢
element.getElementsByClassName // ie9+
element.querySelectorAll // ie8
遍歷 // ie7-
// demo
// HTMl
<body>
<div id="main">
<div id="content">
<p class="info test">info1</p>
<p class="info">info2</p>
<p class="info">info3</p>
</div>
</div>
</body>
// Script
const mainDom = document.getElementById('main');
const infoDomList1 = mainDom.querySelectorAll('.info.test');
const infoDomList2 = mainDom.getElementsByClassName('info test');
複製程式碼
按照Tag查詢
element.getElementsByTagName // ie6+
// demo
// HTMl
<body>
<div id="main">
<div id="content">
<p class="info test">info1</p>
<p class="info">info2</p>
<p class="info">info3</p>
</div>
</div>
</body>
// Script
const divDom = document.getElementsByTagName('div');
const pDom = divDom[0].getElementsByTagName('p');
複製程式碼
按照屬性查詢
element.querySelector //ie8+
element.querySelectorAll() //ie8+
querySelector返回返回的是單個DOM元素,querySelectorAll返回NodeList
querySelector
的語法很類似jquery裡面的選擇器,querySelector
和querySelectorAll
的使用方法是一樣,所以下面的一些說法都是適用於兩個。
// demo
// HTMl
<body>
<div id="main">
<div id="content">
<p class="info test">info1</p>
<p class="info">info2</p>
<p class="info">info3</p>
</div>
</div>
</body>
// Script
const infoDom = document.querySelectorAll('.info');
const infoDom2 = document.querySelectorAll('.info:not(.test)');
複製程式碼
querySelectorAll 和 querySelector 在子查詢下和jquery不是一樣的,詳見DOM元素querySelectorAll可能讓你意外的特性表現 簡單的說就是
document.querySelector("#my-id").querySelectorAll("div div");
,直接感覺是查詢#my-id
的子元素下符合div div
的dom
,其實不是,而是#my-id
的子元素中,同時也符合在全域性範圍內的div div
的dom
。
獲取父元素
element.parentNode // 基本都相容
獲取子元素
element.childNodes // 基本都相容
element.childNodes
不止會獲取到DOM
,也會獲取到文字等,只有當nodeType === 1
時才表示DOM
。
獲取兄弟節點
獲取前面的兄弟節點
element.previousSibling //基本都相容
獲取所有前面的兄弟節點就是遍歷previousSibling
, 直到null
。
Gecko核心的瀏覽器會在原始碼中標籤內部有空白符的地方插入一個文字結點到文件中.因此,使用諸如 Node.firstChild 和 Node.previousSibling 之類的方法可能會引用到一個空白符文字節點, 而不是使用者所預期得到的節點.
獲取後面的兄弟節點
element.nextSibling //基本都相容
獲取所有和注意點都和previousSibling
一樣
DOM操作
建立DOM
document.createElement(tagName)
新增DOM
新增到節點的子節點的最後 append
paranetElement.appendChild(child);
新增到節點的前面
paranetElement.insertBefore(newElement, Element)
通過insertBefore
方法可以將newElement
插入到Element
前面,如果Element
是null
則將newElement
插入到paranetElement
的尾部。
如果newElement
是一個已經存在在文件中的DOM
, insertBefore
則會表現為移動該DOM
(將會保留所有的事件)。
新增到節點的後面
沒有這個函式 ? 可以使用 insertBefore 方法和 nextSibling 來模擬它。
parentDiv.insertBefore(sp1, sp2.nextSibling);
複製程式碼
如果sp2
沒有下一個節點,則它肯定是最後一個節點,則sp2.nextSibling
返回null
,且sp1
被插入到子節點列表的最後面(即sp2
後面)
修改DOM
修改DOM的文案
Element.innerHTML // 獲取標籤內的所有內容 Element.innerText // 只獲取標籤內的文字內容,不包括標籤
修改css
element.style.cssAttribute
修改屬性
element.setAttribute()
element.removeAttribute()
element.className
刪除DOM
paranetElement.removeChild(element)
清空子節點
沒有專門的函式,可以遍歷removeChild來實現
var element = document.getElementById("top");
while (element.firstChild) {
element.removeChild(element.firstChild);
}
複製程式碼
結尾
關於DOM
的操作,常用的暫時只想到這麼多,以後想到了,再慢慢補充