jQuery vs document.querySelectorAll

我多次听说jQuery最强大的资产是它在DOM中查询和操作元素的方式:您可以使用CSS查询来创build复杂的查询,这在常规javascript中很难做到。 不过,据我所知,可以通过document.querySelectordocument.querySelectorAll获得与Internet Explorer 8及更高版本支持的结果相同的结果。

所以问题是这样的:为什么“风险”的jQuery的开销,如果其最强大的资产可以用纯JavaScript实现?

我知道jQuery不仅仅是CSSselect器,例如跨浏览器AJAX,很好的事件附加等等。但是它的查询部分是jQuery实力的一个非常重要的部分!

有什么想法吗?

document.querySelectorAll() 在浏览器中有几个不一致的地方,在旧浏览器中不支持 这可能不会再造成任何麻烦了 。 它有一个非常不直观的范围机制和一些其他不太好的function 。 同样,对于JavaScript,您也很难处理这些查询的结果集,在很多情况下您可能需要这样做。 jQuery提供了如下的函数: filter()find()children()parent()map()not()等等。 更不用说jQuery能够使用伪类select器了。

然而,我不认为这些东西是jQuery最强大的特性,而是其他的东西,比如在dom(事件,样式,animation和操作)上以交叉浏览器兼容方式或ajax接口“工作”。

如果你只想要jQuery的select器引擎,你可以使用jQuery本身使用的那个: Sizzle这样你就可以拥有jQuerys Selector引擎的强大function,而且不会带来讨厌的开销。

编辑:只是为了logging,我是一个巨大的香草JavaScript风扇。 尽pipe如此,事实上有时候需要10行JavaScript代码,你可能会写1行jQuery。

当然,你必须遵守纪律,不要这样写jQuery:

 $('ul.first').find('.foo').css('background-color', 'red').end().find('.bar').css('background-color', 'green').end(); 

这是非常难以阅读,而后者是非常明确的:

 $('ul.first') .find('.foo') .css('background-color', 'red') .end() .find('.bar') .css('background-color', 'green') .end(); 

上面的伪代码说明了等效的JavaScript要复杂得多:

1)find元素,考虑全部元素或只有第一个。

 // $('ul.first') // taking querySelectorAll has to be considered var e = document.querySelector("ul.first"); 

2)通过一些(可能是嵌套的或recursion的)循环迭代子节点数组,并检查类(classlist在所有浏览器中都不可用!)

 //.find('.foo') for (var i = 0;i<e.length;i++){ // older browser don't have element.classList -> even more complex e[i].children.classList.contains('foo'); // do some more magic stuff here } 

3)应用CSS样式

 // .css('background-color', 'green') // note different notation element.style.backgroundColor = "green" // or element.style["background-color"] = "green" 

这个代码至less是你用jQuery编写的代码的两倍。 你也必须考虑跨浏览器的问题,这将危及本地代码的严重速度优势 (除了可靠性之外)。

如果你正在优化你的网页IE8或更新,你应该真的考虑你是否需要jQuery的。 现代浏览器本身就有jQuery提供的许多资源。

如果你关心性能,你可以使用原生的JavaScript有令人难以置信的性能好处(2-10更快) : http : //jsperf.com/jquery-vs-native-selector-and-element-style/2

我把jQuery的div-tagcloud转换为原生javascript (IE8 + compatible),结果令人印象深刻。 快4倍,只需要一点点的开销。

  Number of lines Execution Time Jquery version : 340 155ms Native version : 370 27ms 

您可能不需要Jquery提供了一个非常好的概述,哪个本地方法取代哪个浏览器版本。

http://youmightnotneedjquery.com/


附录:进一步的速度比较原生方法如何与jquery竞争

  • 数组:$ .inArray与Array.indexOf:Jquery 24%慢

  • DOM:$ .empty vs Node.innerHtml:Jquery 97%慢

  • DOM:$ .on vs Node.addEventListener:jquery慢了90%

  • DOM:$ .find vs Node.queryselectorall:jquery慢了90%

  • 数组:$ .grep vs Array.filter:本机慢了70%

  • DOM:$ .show / hide vs display none:Jquery慢了85%

  • AJAX:$ .ajax vs XMLHttpRequest:Jquery慢了89%

  • 身高:$ .outerHeight vs offsetHeight:jquery 87%慢

  • Attr:$ .attr vs setAttribute:jquery慢了86%

要理解为什么jQuery如此受欢迎,了解我们来自哪里非常重要!

大约十年前,顶级浏览器是IE6,Netscape 8和Firefox 1.5。 在那些日子里,除了Document.getElementById()之外,还有一些跨浏览器的方法可以从DOM中select一个元素。

所以,当jQuery 于2006年发布的时候 ,这是非常革命性的。 当时,jQuery为如何轻松select/更改HTML元素和触发事件设定了标准,因为它的灵活性和浏览器支持是前所未有的。

现在,十多年以后,jQuery如此stream行的许多function已经包含在了javaScript标准中:

  • 现在可以使用Document.querySelectorAll()代替jQuery的$() Document.querySelectorAll()
  • 现在可以使用EventTarget.addEventListener()而不是jQuery的$el.on() EventTarget.addEventListener()
  • 而不是jQuery的$el.toggleClass() ,你现在可以使用Element.classList.toggle()

这些在2005年还没有普及。事实上,他们今天的事实显然是在为什么我们应该使用jQuery的问题。 事实上,人们越来越想知道我们是否应该使用jQuery

所以,如果你认为你已经足够了解JavaScript而不用jQuery,那么请做! 不要被迫使用jQuery,只是因为有这么多人在做!

如果可用,jQuery的Sizzleselect器引擎可以使用querySelectorAll 。 它也消除了浏览器之间的不一致,以达到统一的结果。 如果你不想使用所有的jQuery,你可以单独使用Sizzle。 这是一个非常重要的发明。

这里有一些来自源代码的樱花,展示了jQuery(w / Sizzle)为你整理的一些东西:

Safari的怪癖模式:

 if ( document.querySelectorAll ) { (function(){ var oldSizzle = Sizzle, div = document.createElement("div"), id = "__sizzle__"; div.innerHTML = "<p class='TEST'></p>"; // Safari can't handle uppercase or unicode characters when // in quirks mode. if ( div.querySelectorAll && div.querySelectorAll(".TEST").length === 0 ) { return; } 

如果这个守卫失败了,它使用的是Sizzle的一个版本,而不是用querySelectorAll增强的。 更进一步,在IE,Opera和黑莓浏览器中有不一致的具体处理。

  // Check parentNode to catch when Blackberry 4.6 returns // nodes that are no longer in the document #6963 if ( elem && elem.parentNode ) { // Handle the case where IE and Opera return items // by name instead of ID if ( elem.id === match[3] ) { return makeArray( [ elem ], extra ); } } else { return makeArray( [], extra ); } 

如果一切都失败了,它将返回oldSizzle(query, context, extra, seed)

这是因为jQuery可以比querySelectorAll做得更多。

首先,jQuery(尤其是Sizzle)适用于不支持CSS2.1-3select器的IE7-8等浏览器。

另外,Sizzle(这是jQuery背后的select器引擎)为您提供了许多更高级的select器工具,比如:selected伪类,advanced :not()select器,更复杂的语法,如$("> .children")等等。

它完全跨浏览器,完美地提供了jQuery所能提供的所有function(插件和API)。

是的,如果你认为你可以依靠简单的类和idselect器,jQuery对你来说太多了,你会付出夸张的回报。 但是,如果你不这样做,并希望利用所有的jQuery善良,然后使用它。

如果我想要应用相同的属性,比如隐藏“my-class”类的所有元素,这是一个比较。 这是使用jQuery的一个原因。

jQuery的:

 $('.my-class').hide(); 

JavaScript的:

 var cls = document.querySelectorAll('.my-class'); for (var i = 0; i < cls.length; i++) { cls[i].style.display = 'none'; } 

随着jQuery已经如此stream行,他们应该使得document.querySelector()的行为就像$()一样。 相反,document.querySelector()只select第一个匹配的元素,使它只有一半有用。

在代码可维护性方面,坚持使用广泛的库有几个原因。

其中一个主要的是,他们是有据可查的,并有社区,如……说… stackexchange,在那里可以find图书馆的帮助。 使用自定义编码的库,你有源代码,也许是一个方法文件,除非编码器花费更多的时间来logging代码,而不是编写代码,这是罕见的。

编写自己的图书馆可能适合 ,但是坐在下一个办公桌旁的实习生可能会更容易加快jQuery的速度。

如果你喜欢,可以称之为networking效应。 这并不是说jQuery中的代码会更好; 只是代码的简洁性使得更容易掌握所有技能水平的程序员的总体结构,这只是因为在你正在查看的文件中有更多的function代码可见。 从这个意义上说,5行代码比10好。

总之,我认为jQuery的主要优点是简洁的代码和无处不在。

我认为真正的答案是jQuery是在querySelector/querySelectorAll在所有主stream浏览器中都可用之前开发的。

jQuery的最初版本是在2006年 。 事实上,即使jQuery 不是第一个实现CSSselect器的人 。

IE是实现querySelector/querySelectorAll 的最后一个浏览器 。 它的第八版于2009年发布 。

所以现在,DOM元素select器不再是jQuery的最强点。 然而,它仍然有许多好东西,比如更改元素的CSS和html内容,animation,事件绑定,ajax的快捷方式。

正如官方网站所说:“jQuery:写less,多做,JavaScript库”

尝试转换下面的jQuery代码没有任何库

 $("p.neat").addClass("ohmy").show("slow");