DOM同步
先看问题
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<title>Title</title>
<style>
.red {
color: red;
}
.green {
color: green;
}
</style>
</head>
<body>
<ul>
<li class="red">哈哈0</li>
<li class="red">哈哈1</li>
<li class="red">哈哈2</li>
<li class="red">哈哈3</li>
<li class="red">哈哈4</li>
</ul>
<script>
var liArr = document.getElementsByClassName('red');//一绿一红
// var liArr = document.querySelectorAll('.red');//全绿
for (var i = 0; i < liArr.length; i++) {
liArr[i].className = 'green';
}
</script>
</body>
</html>
效果
解释
用 querySelectorAll
会把所有li都改成红色, 但用 getElementsByClassName
只会改变一半li的颜色.
这是因为 querySelectorAll
返回的是一个 Static Node List
, 每次操作之后liArr本身不会改变.
而 getElementsBy
系列的返回的是一个 Live Node List
,每次操作都会实时更新liArr, i++之后就呈现出跳跃的效果了 .
注意事项:
1) querySelectorAll 里要求严格符合CSS规范.
CSS 选择器中的元素名,类和 ID 均不能以数字为开头,下面这种写法将会抛出异常.
try {
var e1 = document.getElementsByClassName('1a2b3c');
var e2 = document.querySelectorAll('.1a2b3c');
} catch (e) {
console.error(e.message);
}
console.log(e1 && e1[0].className);
console.log(e2 && e2[0].className);
getElementById可以接受一个不合法的id,比如
<div id="my.name"></div>
用document.querySelectorAll(‘#my.name’)是query不到它的,
但是用 document.getElementById(‘my.name’)却可以.
2) 查找范围.
querySelectorAll
的查找范围是整个文档.
<div id="test1"><p>test</p></div>
var a = document.getElementById("test1");
a.querySelectorAll("div p").length; // 1
a.getElementsByTagName("div p").length; // 0
a.querySelectorAll("#test1 p").length; // 1
a.getElementsByTagName("#test1 p").length; // 0
a.querySelectorAll("html #test1 p").length; // 1
a.getElementsByTagName("html #test1 p").length; // 0
参考
https://www.zhihu.com/question/24702250