JQuery vs document.querySelectorAll

我曾多次听说 jQuery 最强大的资产是它查询和操作 DOM 中元素的方式: 您可以使用 CSS 查询来创建复杂的查询,这在普通的 javascript 中是非常困难的。 然而,据我所知,你可以用 Internet Explorer 8及以上版本支持的 document.querySelectordocument.querySelectorAll达到同样的效果。

因此,问题是: 如果 jQuery 最强大的资产可以通过纯 JavaScript 实现,为什么还要冒 jQuery 开销的“风险”呢?

我知道 jQuery 不仅仅有 CSS 选择器,比如跨浏览器的 AJAX,漂亮的事件附加等等。但是它的查询部分是 jQuery 强大功能的很大一部分!

有什么想法吗?

204358 次浏览

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

首先,jQuery (特别是 Sizzle)适用于 IE7-8这样不支持 CSS2.1-3选择器的老式浏览器。

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

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

是的,如果你认为你可以依赖于简单的类和标识选择器,jQuery 对你来说太多了,你会付出一个夸张的回报。但是如果你不这样做,并且想要利用 jQuery 的优点,那么就使用它。

document.querySelectorAll() 在不同的浏览器中有一些不一致的地方,并且在旧的浏览器中不支持现在应该不会再有什么麻烦了.它有一个非常不直观的 探测机制和其他一些 filter()0。对于 javascript,处理这些查询的结果集也比较困难,在许多情况下,您可能希望这样做。JQuery 提供了如下函数: filter()find()children()parent()map()not()等等。更不用说 jQuery 处理伪类选择器的能力了。

然而,我并不认为这些是 jQuery 最强大的特性,而是认为其他特性比如 跨浏览器兼容方式或 ajax 界面在 dom (事件、样式、动画和操作)上的“工作”。

如果你只想使用 jQuery 的选择器引擎,你可以使用 jQuery 自己使用的引擎: 译自: 美国《科学》杂志网站(http://sizzlejs.com/)这样你就可以使用 jQuery 的选择器引擎,而不用担心额外的开销。

编辑: 顺便说一句,我是个超级 JavaScript 粉丝。尽管如此,事实上有时候需要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)找到元素,考虑取所有元素或只取第一个元素。

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

2)通过一些(可能是嵌套的或递归的)循环遍历子节点数组,并检查类(类列表在所有浏览器中都不可用!)

//.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"

这段代码的行数至少是您使用 jQuery 编写的代码的两倍。此外,您还必须考虑跨浏览器的问题,这将损害本机代码的 极大的速度优势(除了可靠性之外)。

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

尝试在不使用任何库的情况下翻译以下 jQuery 代码

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

如果可用,jQuery 的 Sizzle 选择器引擎可以使用 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 是在 querySelector/querySelectorAll在所有主流浏览器上都可用之前很久就开发出来的。

JQuery 是在2006年的初始版本。事实上,甚至 jQuery 并不是第一个实现 CSS 选择器的

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

因此,现在 DOM 元素选择器不再是 jQuery 的强项。然而,它仍然有很多好东西,像快捷方式来改变元素的 css 和 html 内容,动画,事件绑定,ajax。

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

其中一个主要原因是它们有很好的文档,并且有诸如... ... 比如... ... stackexchange 之类的社区,在这些社区中可以找到与图书馆有关的帮助。使用自定义编码库,您可以获得源代码,也可以获得 how-to 文档,除非编码人员花费更多的时间编写代码,而不是编写代码,这种情况非常罕见。

编写自己的库可能适用于 ,但坐在隔壁桌的实习生可能更容易掌握 jQuery 之类的东西。

你可以称之为网络效应。这并不是说代码在 jQuery 中会更好; 只是代码的简洁性使得掌握所有技能水平的程序员的整体结构变得更加容易,即使仅仅是因为在你正在查看的文件中可以立即看到更多的函数性代码。从这个意义上说,5行代码比10行好。

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

如果您正在为 IE8或更新版本优化页面,那么您真的应该考虑是否需要 jquery。现代浏览器本身就有许多 jquery 提供的资产。

如果您关心性能,那么使用本地 javascript 可以获得令人难以置信的性能优势: Http://jsperf.com/jquery-vs-native-selector-and-element-style/2

我将 div-tagcloud 从 Jquery转换为 原生 javascript(IE8 + 兼容) ,结果令人印象深刻。只需要一点点开销,就可以提高4倍的速度。

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

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

Http://youmightnotneedjquery.com/


附录: 本机方法与 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 已经如此流行,它们应该使 document.querySelector ()的行为与 $()一样。相反,document.querySelector ()只选择第一个匹配元素,这使得它只有一半的用处。

为了理解 jQuery 为什么如此流行,理解我们从哪里来是非常重要的!

大约十年前,最流行的浏览器是 IE6、 Netscape 8和 Firefox 1.5。在那个年代,除了 强 > Document.getElementById()之外,几乎没有跨浏览器的方法可以从 DOM 中选择元素。

因此,当 jQuery 于2006年释放时,它是相当具有革命性的。当时,jQuery 为如何轻松选择/更改 HTML 元素和触发事件设定了标准,因为它的灵活性和对浏览器的支持是前所未有的。

现在,十多年过去了,许多使 jQuery 如此受欢迎的特性已经包含在 javaScript 标准中:

这些在2005年还不普遍。事实上,它们今天已经很明显地回避了我们为什么要使用 jQuery 的问题。事实上,人们越来越 不知道我们是否应该使用 jQuery

因此,如果您认为自己已经足够了解 JavaScript,可以不使用 jQuery,那么请这样做!不要因为很多人都在使用 jQuery 而感到被迫使用它!

$("#id") vs document.querySelectorAll("#id")

The deal is with the $() function it makes an array and then breaks it up for you but with document.querySelectorAll() it makes an array and you have to break it up.

这是个老问题,但是五年之后,这个问题值得重新讨论。

document.querySelector[All]所有当前的浏览器支持,包括 IE8,所以兼容性不再是一个问题。我也没有发现性能问题(它应该比 document.getElementById慢,但是我自己的测试表明它稍微快一点)。

因此,当涉及到直接操作元素时,它比 jQuery 更受欢迎。

例如:

var element=document.querySelector('h1');
element.innerHTML='Hello';

非常大优于:

var $element=$('h1');
$element.html('hello');

为了做任何事情,jQuery 必须运行100行代码(我曾经跟踪过上面这样的代码,看看 jQuery 实际上是如何处理它的)。这显然是在浪费大家的时间。

JQuery 的另一个重要成本是它将所有内容都包装在一个新的 jQuery 对象中。如果您需要再次展开对象,或者使用对象方法之一来处理已经在原始元素上公开的属性,那么这种开销是特别浪费的。

然而,jQuery 的优势在于它处理集合的方式。如果需要多个元素的 准备好了属性,jQuery 有一个内置的 each方法,它允许这样的事情:

var $elements=$('h2');  //  multiple elements
$elements.html('hello');

使用 Vanilla JavaScript 这样做需要这样的东西:

var elements=document.querySelectorAll('h2');
elements.forEach(function(e) {
e.innerHTML='Hello';
});

有些人觉得这很可怕。

JQuery 选择器也略有不同,但现代浏览器(不包括 IE8)不会获得太多好处。

作为一个规则,我提醒不要在 新的项目中使用 jQuery:

  • JQuery 是一个外部库,增加了项目的开销和对第三方的依赖。
  • JQuery 函数在处理方面非常昂贵。
  • JQuery 强加了一种需要学习的方法,这种方法可能会与代码的其他方面产生竞争。
  • JQuery 在 JavaScript 中公开新特性的速度很慢。

如果以上这些都不重要,那就做你想做的吧。然而,对于跨平台开发来说,jQuery 不再像过去那样重要,因为现代的 JavaScript 和 CSS 比过去走得更远。

这里没有提到 jQuery 的其他特性,但是,我认为它们也需要进一步研究。

只是一个注释,当使用材料设计精简,jquery 选择器不返回属性为材料设计出于某种原因。

致:

<div class="logonfield mdl-textfield mdl-js-textfield mdl-textfield--floating-label">
<input class="mdl-textfield__input" type="text" id="myinputfield" required>
<label class="mdl-textfield__label" for="myinputfield">Enter something..</label>
</div>

这种方法是有效的:

document.querySelector('#myinputfield').parentNode.MaterialTextfield.change();

这不是:

$('#myinputfield').parentNode.MaterialTextfield.change();