querySelector

querySelector测试效果

拭目以待 发布于

Html5中有个querySelector方法,用于根据css选择符选择,看上去与jquery 的 Sizzle功能相似,写了个demo进行了一些验证。

有这么一段html

<div class="test1" id="id1">test1</div>
<p class="test2">test2</p>
<div class="test2">test2</div>
<p test3>test3</p>
<p style="display:none;">test4</p>

接下来我们开始使用jquery的使用习惯进行测试


1、通过id来获取:

var id1 = document.querySelector('#id1');
console.log(id1); //<div class="test1" id="id1">test1</div>

获取到了id=id1的node element,等同于jquery的 $('#id1').get(0)


2、通过标签名称获取:

var div = document.querySelector('div');
console.log(div);//<div class="test1" id="id1">test1</div>

获取到了标签为div的元素,等同于jquery的$('div').get(0)


3、通过className获取:

var test2 = document.querySelector('.test2');
console.log(test2); //<p class="test2">test2</p>

获取到了className=test2的元素,等同于jquery的$('.test2').get(0)


4、通过自定义属性进行获取:

var test3 = document.querySelector('[test3]');
console.log(test3); //p

获取到了包含自定义属性test3的node element,等同于$('[test3]')

到这里,发现querySelector()只会获取到第一个匹配的元素,这一点上与jquery sizzle 有所不同。这一点从习惯上是不大能接受的。查看文档发现HTML5在推出querySelector()的同时还一并推出了querySelectorAll()方法。该方法与querySelector()方法所接收的参数相同,不同的是该方法会返回所有相匹配的元素。

下面来试一下querySelectorAll()


1、获取所有DIV标签元素:

var allDiv = document.querySelectorAll('div');
console.log(allDiv);  // [div#id1.test1, div.test2]

通过querySelectorAll()获取到的元素为组数类型,每一个值对应一个node element。那么该如何获取其中的某个节点?


2、获取DIV标签的第二个节点:

var secondDiv = document.querySelectorAll('div').item(1);
console.log(secondDiv); //<div class="test2">test2</div>

使用item()方法,传入对应的索引值即可获得。除过这样还可以使用方括号进行获取,等同于jquery的get()方法。原生的方法可以如此支持,那兼容性如何?


兼容性问题:

现以全面支持IE8+,FireFox3.5+,Safari3.1+,Chrome和Op10+

IE8都支持了,是不是jquery的Sizzle 要完全要被替代了?我们来试几个复杂的CSS选择器。


1、div:first-child:

var firstDiv = document.querySelector('div:first-child');
console.log(firstDiv) //div#id1.test1

这个没问题,再来一个


2、div:last-child:

var lastDiv = document.querySelector('div:last-child');
console.log(lastDiv) //null

返回为null,表明该选择器不能找到对应的节点,再试一个。


3、p:hidden:

var displayNone =document.querySelector('p:hidden');
console.log(displayNone);  // null

依旧返回null,表明p:hidden这种形式的也不支持。


由此可见,querySelector并不能完全替代jquery Sizzle的,jquery sizzle所表现的实力依旧明显。当然原生的方法性能上要优于jquery,查看了下源码,发现从1.7.2版本开始(在之前的没有去找,有在再早之前发现的可以联系下我)。现贴出的为2.1.4系列中jquery Sizzle中对querySelectorAll方法的处理。
#jquery.2.1.4.js 1119行
function( tag, context ) {
if ( typeof context.getElementsByTagName !== "undefined" ) {
return context.getElementsByTagName( tag );
// DocumentFragment nodes don't have gEBTN
} else if ( support.qsa ) {
return context.querySelectorAll( tag );
}
}


由源码中可以看出,jquery中很早就对querySelector进行使用。所以如果项目中有引用的jquery,则无需使用querySelector与querySelectAll。

jquery经典绝非偶然