网站首页 » 前端开发 » JavaScript » document.querySelector()
上一篇:
下一篇:

document.querySelector()

前言

在平时的前端开发中,我们经常需要写一些小效果,比如TAB切换、图片轮播等等,不管是写什么 JavaScript 效果,你肯定离不开获取元素作为对象,然后对这个对象进行一系列的操作。而获取元素时,我们可以使用jQuery 库,也可以使用 JavaScript 为我们提供的原生的并且比较常用的方法getelementbyid()、getelementbyTagName()、getElementsByClassName()。但是本文要跟大家分享是另一种方法也是 JavaScript 原生的实现方法,它就是document.querySelector(),它的强大之处就是,你可以像使用 jQuery 库的选择器一样使用它,但它也有不足之处,好,我们来看看这家伙到底是何方神圣。

简单介绍

Returns the first element within the document (using depth-first pre-order traversal of the document’s nodes|by first element in document markup and iterating through sequential nodes by order of amount of child nodes) that matches the specified group of selectors.
译:返回指定元素节点的子树中匹配selector的集合中的第一个,如果没有匹配,返回null。

基本语法

element = document.querySelector(selectors);

element 是一个对象
而选择器selectors是一个包括一个或者多个CSS选择器的字符串,选择器这间用逗号,隔开

注意

1.如果没有找到匹配元素,返回null ;否则返回第一个匹配的元素。

2.如果匹配的ID,而这个ID被错误在页面中多次使用,那么querySelector 返回第一个匹配的ID元素

3.如果选择器值无效,那么querySelector 会抛出一个语法错误(SYNTAX_ERR exception)

4.querySelector 的字符串参数命名一定要遵循 CSS 语法规则

5.CSS伪元素将不会返回任何元素。

要匹配的ID或选择不遵循CSS的语法(如:使用一个冒号或空格),则必须用一个反斜杠字符。因为反斜杠是JavaScript中的转义字符,如果你正在输入一个字符串,则必须转义两次(一次是JavaScript的字符串,另一次是querySelector):

<div id="foo\bar"></div>
<div id="foo:bar"></div>

<script>
console.log('#foo\bar') // "#fooar"
document.querySelector('#foo\bar') // Does not match anything

console.log('#foo\\bar') // "#foo\bar"
console.log('#foo\\\\bar') // "#foo\\bar"
document.querySelector('#foo\\\\bar') // Match the first div

document.querySelector('#foo:bar') // Does not match anything
document.querySelector('#foo\\:bar') // Match the second div
</script>

高级用法

上面说的有点前卫,毕竟我们很少会像上面那样来给选择器起这么特别的名称。我们还是来看点接地气的用法吧,接地气才是王道。

获取文档中第一个 <div> 元素:

document.querySelector("div");

获取文档中 class=”example” 的第一个元素:

document.querySelector(".example");

获取文档中 class=”example” 的第一个 <div> 元素:

document.querySelector("p.example");

获取文档中 id=”example” 的第一个 <div> 元素:

document.querySelector("#example");

获取文档中有 “target” 属性的第一个 <a> 元素:

document.querySelector("a[target]");

你甚至不可以这样写

document.querySelector("div.test>p:first-child");

总之,在css中能用的选择器,对于 querySelector 来说用起来一点压力都没有。

兼容性

canvas 浏览器支持情况

但是 querySelector 也不是超能的,有时候它对自己也不满意,在哪些方面不满意呢?除了不兼容IE6、IE7外,还有一个重要重不是很致使的问题,querySelector 性能问题。下面我们就来看看 querySelector 的性能如何

性能分析

我们可以通过下面这段代码来简单地分析下querySelector 性能以及它的性能与getElementById 的性能的对比

HTML 代码

<div id="test">
 <p>querySelector()</p>
 <p>querySelector()</p>
 <p>querySelector()</p>
 <p>querySelector()</p>
</div>

JavaScript 代码

console.time('querySelector');
for (var i = 0; i < 1; i++) {
 document.querySelector("#test");
}
console.timeEnd('querySelector');

console.time('getElementById');
for (var i = 0; i < 1; i++) {
 document.getElementById("test");
}
console.timeEnd('getElementById');

把下面这段代码放到script标签中运行,然后在console 里查看两个方法分别耗时多少,你会发现 getElementById 远远的把 querySelector 甩了好几百公里远。数据说了算

名称 / 数据组 1 2 3 4 5 平均值(去最高、最低)
querySelector() 0.715ms 0.486ms 0.498ms 0.500ms 0.483ms 0.4946666666666667
getElementById() 0.020ms 0.014ms 0.025ms 0.017ms 0.112ms 0.0206666666666667

循环1次

虽然不是基于大数据的分析,但简单的分析也可以粗略地得出 getElementById 的性能比 querySelector 的性能强了24倍多。但这样也太过鲁莽了,我们不妨再给 querySelector  一个翻身的机会。我们让上面的测试代码循环次数从1次改成1000000次,结果会不会出现转机呢?我们还是来看看吧。

名称 / 数据组 1 2 3 4 5 平均值(去最高、最低)
querySelector() 124.217ms 125.246ms 128.401ms 124.243ms 123.703ms 124.5686666666667
getElementById() 47.062ms 47.516ms 46.579ms 48.068ms 46.701ms 47.093

循环1000000次

因此我们可以得到 getElementById 在性能方面更有优势,并且随意操作次数的增加 getElementById 性能 与querySelector 性能比越小。

虽然 querySelector()getElementById() 的分出了胜负,但对于我们使用querySelector()方法来获取元素还是没多大的影响,为什么?我觉得原因如下:

1.querySelector 确实比 getElementById 强大好用
2.在实践项目中,也很少(几乎不会出现)有大量的DOM获取操作
3.毫秒级的差别,对于用户来说,可以忽略不计(这个得看情况)。

所以我觉得 querySelector 还是可以大胆的用到实际项目中的。

分析完了querySelector 与 getElementById 的性能比较,下面我们顺便也说说 querySelectorAll 与 getElementsByTagName 的性能数据比较

测试的代码基本没怎么变(HTML不变,只是把querySelector()改成了querySelectorAll()以及把getElementById()改成了getElementsByTagName())。

JavaScript 代码

console.time('querySelector');
for (var i = 0; i < 10; i++) {
 document.querySelectorAll('p');
}
console.timeEnd('querySelector');

console.time('getElementsByTagName');
for (var i = 0; i < 10; i++) {
 document.getElementsByTagName('p');
}
console.timeEnd('getElementsByTagName');
名称 / 数据组 1 2 3 4 5 平均值(去最高、最低)
querySelectorAll() 0.070ms 0.049ms 0.090ms 0.050ms 0.055ms 0.0583333333333333
getElementsByTagName() 0.034ms 0.035ms 0.101ms 0.069ms 0.034ms 0.034ms

循环1次

循环1次数据就显得很让人满意,相差不大。

下面是循环1000000次的数据

名称 / 数据组 1 2 3 4 5 平均值(去最高、最低)
querySelectorAll() 635.685ms 665.229ms 714.814ms 735.351ms 695.975ms 692.006
getElementsByTagName() 57.606ms 58.181ms 58.366ms 58.424ms 57.535ms 58.051

循环1000000次

循环1000000次数据就有点尴尬了,querySelectorAll()耗时竟然接近700ms,而getElementsByTagName()只用了58毫秒多一点点。

总结

如果你像我这样,性格中偏完美主义阵营的,那么你可以像下面这样使用获取元素的方法(下面的建议是基于以上数据的)。

1.如果只是获取一个元素那么可以用getElementById()querySelectorAll()

2.如果是要获取很多个元素的那么你可以用getElementsByTagName()

不管怎么样,总之平时想怎么折腾这些 JavaScript 获取元素的方法都可以,不管是getElementById()getElementsByTagName()、还是本文介绍的querySelector(),都可放心使用,我相信随着信息技术的发展,这种差异会不值提。

相关资料

火狐MDN:https://developer.mozilla.org/en-US/docs/Web/API/Document/querySelector

  • 微信扫一扫,赏我

  • 支付宝扫一扫,赏我

声明

原创文章,不经本站同意,不得以任何形式转载,如有不便,请多多包涵!

本文永久链接:http://yunkus.com/document-queryselector/

发表评论

电子邮件地址不会被公开。 必填项已用*标注

评论 END