第15章 DOM扩展
# Selectors API
- querySelector()
- querySelectorAll()
# 元素遍历
Element Traversal API 为 DOM 元素新增了 5 个属性
- childElementCount,返回子元素数量,不包含文本节点和注释。
- firstElementChild,指向第一个 Element 类型的子元素。
- lastElementChild,指向最后一个 Element 类型的子元素。
- previousElementSibling,指向前一个 Element 类型的同胞元素。
- nextElementSibling,指向后一个 Element 类型的同胞元素。
下面的代码演示了如何遍历元素节点。
<style>
.child {
width: 100px;
height: 100px;
border: 1px solid;
display: inline-block;
}
</style>
<body>
<button>点我</button>
<div class="parent">
<div class="child"></div>
<div class="child"></div>
<div class="child"></div>
<div class="child"></div>
<div class="child"></div>
</div>
</body>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
const button = document.querySelector('button')
button.onclick = async function() {
let parent = document.querySelector('.parent')
let current = parent.firstElementChild
while (current) {
await processChild(current)
if (current === parent.lastElementChild) break
current = current.nextElementSibling
}
async function processChild(element) {
await sleep(100)
element.style.background = 'skyblue'
}
}
function sleep(time) {
return new Promise((resolve) => setTimeout(resolve, time))
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
其遍历方式和链表遍历一模一样。
# HTML5
# CSS 类扩展
由于开发者大量使用 class 属性,因此新增了方便使用 CSS 类的特性。
getElementsByClassName():接收一个参数,即包含一个或多个类名的字符串。
// 取得所有包含 li 和 li4 的元素 let allNames = document.getElementsByClassName('li li4') // 取得ul类的元素子树中所有的li类的元素 let selected = document.querySelector('.ul').getElementsByClassName('li')
1
2
3
4classList 属性
在该属性之前,操作类名可以通过 className 属性来实现添加、删除和替换,但操作较复杂。
<div class="bd user disabled">a</div>
1// 要删除的class类 let targetClass = 'user' // 把类名拆成数组 let classNames = div.className.split(/\s+/) // 找到要删除类名的索引 let index = classNames.indexOf(targetClass) // 如果有,则删除 if (index > -1) { classNames.splice(index, 1) } // 重新设置类名 div.className = classNames.join(' ')
1
2
3
4
5
6
7
8
9
10
11
12className 是一个字符串,所以需要转为数组。
classList 是一个 DOMTokenList 的集合,包括以下方法
- add(value):向类名列表中添加指定的字符串值,不会重复添加。
- contains(value):检测给定的 value 是否存在。
- remove(value):从类名列表中删除指定的字符串值。
- toggle(value):切换 value 值,有则删除,无则添加。
前面删除类的操作可以简化:
div.classList.remove('user')
1
# HTMLDocument 扩展
document.readyState:检测文档是否加载完毕,有 2 个状态。
- loading,文档正在加载
- complete,文档加载完成
document.head:指向文档的<head>元素.
# 自定义数据属性
使用前缀data-
设置自定义属性,可以通过元素的dataset
属性访问
<div data-appId="12345">a</div>
1
console.log(div.dataset.appId) // undefined
console.log(div.dataset.appid) // 大写字母会转为小写
div.dataset.appId = 'abcd' // 如果有大写,则会分裂为小写,如data-app-id
div.dataset.appid = 'abcd' // 如果有大写,则会分裂为小写,如data-app-id
1
2
3
4
2
3
4
# 插入标记
innerHTML 属性:可读可写,可以得到和设置元素所有的后代 HTML 字符串。
outerHTML 属性:可读可写,会得到和设置包括元素自身的字符串。
<button>点我</button>
<div>a</div>
1
2
2
const button = document.querySelector('button')
const div = document.querySelector('div')
button.onclick = function() {
// div.innerHTML = '<span>b</span>' // 替换div下所有的子节点
div.outerHTML = '<span>c</span>' // 会替换整个div元素
}
1
2
3
4
5
6
7
2
3
4
5
6
7
此外还有 2 个新增方法:insertAdjacentHTML()和 insertAdjacentText()。
谨慎使用 innerHTML 呈现用户提供的信息,不建议使用,会导致 XSS 攻击。innerHTML 虽然无法执行<script>标签,但并不限制 js 能力,如添加 onclick 属性。
# scrollIntoView()
可以滚动浏览器窗口或容器元素,从而使目标元素进入视口。
入参可以是布尔值,也可以是一个选项对象。
- alignToTop 布尔值,true 表示窗口滚动后元素的顶部与视口顶部对齐,false 相反。
- scrollIntoViewOptions 选项对象
- behavior:过渡动画,可取的值为"smooth"和"auto"
- block:定义垂直方向的对齐,可取值为"start","center","end","nearest"
- inline:定义水平方向的对齐,可取值为"start","center","end","nearest"
<style>
.li {
width: 300px;
height: 300px;
border: 1px solid;
}
</style>
<body>
<button>点我</button>
<div class="ul">
<div class="li">1</div>
<div class="li">2</div>
<div class="li">3</div>
<div class="li li4">4</div>
<div class="li">5</div>
<div class="li">6</div>
<div class="li">7</div>
</div>
</body>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
const button = document.querySelector('button')
const div = document.querySelector('div')
button.onclick = function() {
const div4 = document.querySelector('.li4')
// div4.scrollIntoView()
// div4.scrollIntoView(true)
div4.scrollIntoView({ behavior: 'smooth', block: 'end' })
}
1
2
3
4
5
6
7
8
9
2
3
4
5
6
7
8
9
# 专有扩展
本小节是未标准化的特性,但已基本被主流浏览器支持。
# children 属性
表示只包含元素的子节点。
# contains()
确定一个元素是不是另一个元素的后代。
# innerText 属性
对应元素中包含的所有文本内容。
上次更新: 2022/01/14, 08:52:26