共计 1833 个字符,预计需要花费 5 分钟才能阅读完成。
虽然现在 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):如果列表中已经存在给定的值,删除它;如果列表中没有给定的值,添加它。