在React、Vue框架流行的今天,操作DOM这种方式已经用的比较少了,不过工作中有时候还是会用到的。今天就来说一下QS/QSA和GEBI/GEBC(这里为了方便偷个懒使用了缩写)的区别。
1. 兼容性:
上图是我从大名鼎鼎的Can I Use上截的图,可以看到各个浏览器对于这几种的支持情况。
结论:
如果你不考虑兼容特定版本的浏览器,这一点你可以忽略。
2. 效率:
首先我们来比较 GEBI和QS 的差别,创建测试文件如下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<div id="test"></div>
<script>
console.time('querySelector');
for (var i = 0; i < 100000; i++) {
document.querySelector("#test");
}
console.timeEnd('querySelector');
console.time('getElementById');
for (var i = 0; i < 100000; i++) {
document.getElementById("test");
}
console.timeEnd('getElementById');
</script>
</body>
</html>
复制代码
我们再创建一个测试文件来比较GEBC和QSA,如下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<div class="test"></div>
<div class="test"></div>
<div class="test"></div>
<script>
console.time('querySelectorAll');
for (var i = 0; i < 10000; i++) {
document.querySelectorAll(".test");
}
console.timeEnd('querySelectorAll');
console.time('getElementsByClassName');
for (var i = 0; i < 10000; i++) {
document.getElementsByClassName("test");
}
console.timeEnd('getElementsByClassName');
</script>
</body>
</html>
复制代码
结论:
总的来说QS和QSA要比GEBI和GEBC要慢。
有人要问了,这QS和QSA不是后来提出来的吗?为什么效率这么低还要用?不要着急,接下来我们就要讲到了。
灵活性:
QS/QSA 均支持CSS的选择器,也就是说你可以这么写:
querySelector('div img .test')
//找到div下面的img下面类名为test的元素
复制代码
怎么样?GEBI和GEBC做不到吧,他们只能选择固定id或者固定类名,在这一点上QS/QSA差距还是挺大的(QS/QSA 不能使用伪类选择器)。
结论:
- QS/QSA相较于GEBI/GEBC更加灵活和方便
- QS/QSA对于CSS伪类选择器不生效,具体见mdn querySelector
动态性:
接下来我们来讨论QSA与GEBC最大的区别动态性。不知道我在说什么?没关系继续往下看吧。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<script>
a = document.querySelectorAll('img')
b = document.getElementsByTagName('img')
document.body.appendChild(new Image())
console.log(a.length) // 0
console.log(b.length) // 1
</script>
</body>
</html>
复制代码
结论:
通过QSA选择的不受后来DOM变化的影响,但是通过GEBC会受DOM的影响。
总结:
QS/QSA 给我们提供了极大的灵活性和便利性,但性能相较GEBI/GEBC有一定差距,并且兼容性上存在一定差距。再不引入第三方库如jQuery的情况下,使用哪种要根据具体需求来定,找到最优的解决方案即可。