雖然現在MVVM框架帶來了諸多便利,但你真的就不再需要操作DOM了嗎?本文通過幾個小例子來介紹一些DOM操作的小技巧
場景一:querySelectorAll
陸小雞最近遇到了這樣一個問題,他引用了一個第三方的表格元件,他引入元件的程式碼如下:
<jj-table id="mytable"></jj-table>
元件渲染後的結構大致如下:
<div class="table-wrapper" id="mytable">
<div class="table-header">
<table></table>
</div>
<div class="table-body">
<table>
<tbody class="table-tbody"></tbody>
</table>
</div>
</div>
為了獲取tbody這個dom節點,他寫下了如下程式碼:
var el = document.getElementsByClassName(`table-tbody`)[0]
console.log(el)
控制檯列印一看,發現有點不對啊,原來這個頁面中還引入了一個表格,這種方式得到的是頁面中的第一個表格,並不是這個表格。所以,他改進了下程式碼:
var mytable = document.getElementById(`mytable`)
var el = mytable.getElementsByClassName(`table-tbody`)[0]
這下終於正確了。但是,善於思考的小雞同學又想了想,如果層級更復雜,那寫起來不是很麻煩嗎?能不能像css選擇器一樣選擇DOM節點呢?最終,他寫下了如下程式碼:
var el = document.querySelectorAll(`#mytable tbody`)[0]
有人可能會說,jQuery不就是通過CSS選擇符
查詢DOM文件取得元素的引用嗎?沒錯!但通過querySelectorAll方法,原生也可以做到。
注意:還有一個類似的方法querySelector(),其接收的引數與 querySelectorAll()方法一樣,都是一個 CSS 選擇符,但返回的是一個元素而不是所有匹配的元素(一個 NodeList 的例項)。
場景二:classList
張大鵬最近遇到了這樣一個問題,需要找到表格中各行的序列號,將其存入ids陣列中,其中的序列號已經寫入到每行的class類名中,如下:
<table>
<tbody class="table-tbody">
<tr class="table-row 1">
<td>td1</td>
</tr>
<tr class="table-row 4">
<td>td4</td>
</tr>
<tr class="table-row 2">
<td>td2</td>
</tr>
<tr class="table-row 3">
<td>td3</td>
</tr>
</tbody>
</table>
他略加思索,寫出瞭如下程式碼:
var el = document.querySelectorAll(`.table-tbody`)[0]
var rows = el.rows
var ids = []
for (var i = 0; i < rows.length; i++) {
let classNames = rows[i].className
ids.push(classNames.split(` `)[1])
}
console.log(ids)
看上去是不錯啊,但是感覺獲取類名有點麻煩,並且還得進行一次型別轉換才能取到序列號,能不能一步到位呢?
通過查閱,他寫出瞭如下程式碼:
var el = document.querySelectorAll(`.table-tbody`)[0]
var rows = el.rows
var ids = []
for (var i = 0; i < rows.length; i++) {
ids.push(rows[i].classList[1])
}
console.log(ids)
HTML5 新增了一種操作類名的方式,可以讓操作更簡單也更安全,那就是為所有元素新增classList 屬性。這個新型別還定義如下方法:
- add(value):將給定的字串值新增到列表中。如果值已經存在,就不新增了。
- contains(value):表示列表中是否存在給定的值,如果存在則返回 true,否則返回 false。
- remove(value):從列表中刪除給定的字串。
- toggle(value):如果列表中已經存在給定的值,刪除它;如果列表中沒有給定的值,新增它。