在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的情況下,使用哪種要根據具體需求來定,找到最優的解決方案即可。