171

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

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

我知道 jQuery 不仅仅是 CSS 选择器,例如跨浏览器 AJAX、漂亮的事件附加等。但它的查询部分是 jQuery 强大的一个非常重要的部分!

有什么想法吗?

4

12 回答 12

135

document.querySelectorAll() 跨浏览器有几个不一致的地方,并且在旧浏览器中不受支持现在这可能不会再造成任何麻烦了。它有一个非常不直观的作用域机制和其他一些不太好的特性。同样,使用 javascript,您会更难处理这些查询的结果集,而在许多情况下,您可能想要这样做。jQuery 提供了处理它们的函数,例如:filter()find()children()parent()map()等等not()。更不用说 jQuery 使用伪类选择器的能力了。

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

如果您只想要 jQuery 的选择器引擎,您可以使用 jQuery 本身正在使用的一个:Sizzle这样您就拥有了 jQuerys 选择器引擎的强大功能,而不会产生讨厌的开销。

编辑:为了记录,我是一个巨大的香草 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 编写的代码行数的两倍。此外,您还必须考虑跨浏览器问题,这将损害本机代码的严重速度优势(除了可靠性之外)。

于 2012-07-16T11:44:26.877 回答
66

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

如果您关心性能,则可以使用本机 javascript 获得令人难以置信的性能优势(快 2-10 倍) :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

You Might Not Need Jquery 提供了一个非常好的概述,哪些本地方法替换了哪个浏览器版本。

http://youmightnotneedjquery.com/


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

于 2014-02-03T22:24:17.030 回答
21

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

大约十年前,顶级浏览器是 IE6、Netscape 8 和 Firefox 1.5。在那个时候,除了Document.getElementById().

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

现在,十多年后,许多让 jQuery 如此流行的特性已经包含在 javaScript 标准中:

这些在 2005 年并不普遍可用。它们今天的事实显然引出了我们为什么应该使用 jQuery 的问题。事实上,人们越来越想知道我们是否应该使用 jQuery

所以,如果你认为你对 JavaScript 的理解足够好,可以不用 jQuery,请这样做!不要因为很多其他人都在使用 jQuery 而感到被迫使用 jQuery!

于 2016-03-29T20:59:41.060 回答
9

那是因为 jQuery 可以做的远不止querySelectorAll.

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

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

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

是的,如果你认为你可以依赖简单的类和 id 选择器,那么 jQuery 对你来说太过分了,你会付出夸大的回报。但如果你不这样做,并且想利用所有 jQuery 的优点,那么就使用它。

于 2012-07-16T11:42:58.917 回答
8

querySelectorAll如果可用,可以使用 jQuery 的 Sizzle 选择器引擎。它还消除了浏览器之间的不一致,以实现统一的结果。如果你不想使用所有的 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 和 Blackberry 浏览器中的不一致的特定处理。

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

于 2012-07-16T12:00:13.960 回答
6

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

其中一个主要的原因是它们有很好的文档记录,并且拥有诸如 ... 说 ... stackexchange 之类的社区,可以在其中找到有关图书馆的帮助。使用自定义编码库,您可以获得源代码,可能还有操作指南文档,除非编码人员花费更多时间记录代码而不是编写代码,这非常罕见。

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

如果你愿意,可以称之为网络效应。这并不是说代码在 jQuery 中会更好;只是代码的简洁性使得所有技能水平的程序员都更容易掌握整体结构,如果只是因为在您正在查看的文件中一次可见更多的功能代码。从这个意义上说,5 行代码优于 10 行。

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

于 2013-07-16T15:32:11.190 回答
6

如果我想应用相同的属性,这是一个比较,例如隐藏类“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() 只选择第一个匹配的元素,这使得它只有一半有用。

于 2015-10-18T05:46:29.930 回答
5

老问题,但五年后,值得重温。这里我只讨论 jQuery 的选择器方面。

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

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

例如:

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

大大优于:

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

为了做任何事情,jQuery 必须运行一百行代码(我曾经通过类似上面的代码来查看 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 的其他特性。但是,我认为他们也需要仔细研究。

于 2018-03-06T05:45:35.620 回答
3

正如官方网站所说:“jQuery: The Write Less, Do More, JavaScript Library”

尝试在没有任何库的情况下翻译以下 jQuery 代码

$("p.neat").addClass("ohmy").show("slow");
于 2012-07-16T11:56:23.290 回答
2

我认为真正的答案是 jQuery 早querySelector/querySelectorAll在所有主流浏览器都可用之前就已经开发出来了。

jQuery 的初始版本是在 2006 年。事实上,即使 jQuery也不是第一个实现 CSS 选择器的

IE 是最后一个实现querySelector/querySelectorAll. 其第 8 版于 2009 年发布

所以现在,DOM 元素选择器不再是 jQuery 的强项了。然而,它仍然有很多好东西,比如更改元素的 css 和 html 内容的快捷方式、动画、事件绑定、ajax。

于 2013-07-16T14:31:02.247 回答
0

只是对此的评论,当使用 Material Design lite 时,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();
于 2018-09-18T19:00:27.900 回答
0
$("#id") 与 document.querySelectorAll("#id")

处理的是 $() 函数,它创建一个数组,然后为您分解它,但使用 document.querySelectorAll() 它创建一个数组,您必须分解它。

于 2017-11-29T15:19:58.363 回答