为啥过时的 jQuery 仍然是市场占有率最高的 JS 库?
作者:ConardLi来源:code秘密花园
jQuery 于 2006 年推出,当时 Ajax 一词正炒的火热。Ajax(Asynchronous JavaScript and XML)与早期 Web 2.0 时代的其他 JavaScript 技术一样,早已不再是开发者的常用语。
但 jQuery 经受住了时间的考验,事实上直到最近它还在保持逐年增长。对此, jQuery 的开发者 Michał Gołębiowski-Owczarek 分享了他的看法。
名字太长了,后面简称他 MGO 吧。
MGO 是上个月 OpenJS 博客上两篇文章的作者,里面都提到了 jQuery 正在进行的 现代化工作。
第一篇文章宣布了 jQuery UI 的新版本 —— 一个构建在 jQuery Core 库之上的用户界面库。这将是 该项目的最终版本,这意味着 jQuery UI 后面不再会有大的迭代了,仅仅会保持维护状态。
第二篇文章宣布弃用了 jQuery Mobile,这是 jQuery 的另一个子项目,为移动浏览器提供 基于 HTML5 的用户界面系统。
不过,这两个项目的结束都不会影响 jQuery 现在的主项目:jQuery Core,这意味着它短时间内不会消失在大众视野。
虽然 jQuery 现在正在被大量使用,但现在的开发者甚至可能没有意识到他们在使用 jQuery。那是因为它被嵌入在了许多大型开源项目里面 —— 其中最著名的就是 WordPress。
很多 WordPress 的主题和插件都依赖于 jQuery。jQuery 库也是当今一些最流行的 JavaScript 框架和工具包的基础层,例如 AngularJS 和 Bootstrap(4.0 及以下版本)。
其实大多数网站都不需要复杂的开发框架,它们大多是具有一些动态行为的静态网站(这种网站通常都会用 WordPress 编写),jQuery 在这个场景下仍然很流行,因为它既简单又有效。
而且,在未来的很长一段时间,jQuery 还继续会是 WordPress 的一部分,因为它很难在不破坏向后兼容性的情况下将它删除。
随着时间的推移, WordPress 肯定会逐步更新它的技术,但是这应该是一个渐进式的过程。
但是, WordPress 的社区里已经出现了一些反对的声音, 在 WordPress 主题中使用 jQuery 的性能影响 就是一个比较热门的话题。
GMO还表示:jQuery死了吗? 这样的文章已经流传了好几年了,至少目前在 WordPress 生态系统中它仍然很活跃。如果谁鼓励开发者们把它替换掉,风险自负。
当 jQuery 的创造者 John Resig 于2006 年 1 月在 BarCampNYC 发布它的以一个版本时,他写道:
这段代码彻底改变了让 Javascript 与 HTML 交互的方式。
他主要指的是 jQuery 使开发者可以更轻松地操作 DOM。要知道,这是在谷歌浏览器逆袭之前,现在微软臭名昭著的 Internet Explorer 占据了 85-90% 的浏览器市场,其中 IE6 占主导地位。即使在当时,IE6 也以历史上最糟糕的浏览器而闻名。
Resig 还在2006 年 6 月的一篇帖子中指出了 JavaScript 开发者在浏览器上遇到的一些问题:
JavaScript 中存在许多问题(其中大部分源于浏览器不兼容),任何稍微复杂一点的应用程序都需要处理诸如规范化事件处理、DOM 节点选择、动画渲染这些问题。
这也正是 Resig 着手解决的问题。当时“四大”领先的 JavaScript 库是 Dojo、MochiKit、Prototype/Scriptaculous 和 Yahoo UI 。
所以基本上,jQuery 的发明主要是为了帮助开发者处理当时浏览器的不足。
在现在各种好用的浏览器都在更加符合 Web 标准的时候,jQuery 现在在 Web 中扮演的角色是啥呢?
此外,JavaScript 标准本身在过去十年中也得到了显着改进,尤其是在 2015 年 ECMAScript 6 发布之后。
现在, React 已成为当今最受关注的 JavaScript 库。很多现代框架,尤其是 Next.js,都是建立在 React 之上的。
一些其他流行的框架,例如 Angular 都有自己的库生态系统。现在的 JavaScript 框架还允许你将 UI 分解为各种组件,从而更轻松地扩展应用程序。
GMO 谈到 Next.js 和 Angular 的时候提到:
这些框架提供了抽象,可以更轻松地在数据和视图之间进行同步。因此他们的用户不再需要如此频繁地直接修改或者访问 DOM,并且通常也不鼓励这样做。在这样的环境下,使用 jQuery 没有多大意义。但这只是整个网络生态系统的一小部分。
然而 GMO 也承认 jQuery 可能存在大规模应用程序的性能问题:
这些年来,我们大大提高了 jQuery 的性能,但也存在一些难以应对的问题。其中之一是为了不与浏览器冲突,jQuery 不会修改原生原型 — 就像其他一些库所做的那样(通常后来导致冲突 API 的标准化问题)— 而是用 jQuery 包装器对象包装 DOM 节点。每个操作都会创建一个新的这种包装器对象,在大多数情况下,这并不重要,但对于具有大量 DOM 操作的非常复杂的应用程序,这可能会成为一个问题。
很明显,jQuery 不再是开发者将 JavaScript 功能添加到他们的网站或应用程序的最佳方式,尤其是在需要扩展的情况下。
GitHub 对 jQuery 的贡献远低于其高峰年(2006 年至 2013 年左右)的事实,这也意味着要使 jQuery 与我们现在的 Web 更加兼容,我们还需要做更多的事情。
不过没关系。jQuery 的持续时间比大多数开发者预期的要长得多,因为它是在 Web 2.0 时代开始时问世的。毕竟,它现在仍然可以完成它所要做的工作,而且它仍然是一个非常简单方便的 JavaScript 库。
无论如何,在未来几年内,jQuery 还会嵌入到数以千万计的 WordPress 网站中,它甚至可能比 React 更持久。
对此你怎么看呢?
jQuery 已“死”?为清除技术债,我们删掉了前端所有 jQuery 依赖
近期,英国公共部门站 GOV.UK 前端开发主管 Matt Hobbs 宣布该公司删除了 jQuery 作为所有前端应用程序的依赖项,这意味着“在所有 13 个 FE 应用程序中,JS 大小减少了 32 KB(31% ~49% 之间)”。
Matt 也在推特上分享了几组数据,说明了在删除 jQuery 后一些关键指标得到了优化。
- 移除页面标签限制并查看所有页面 RUM 数据, 75% 用户的页面都有类似的下降:
- 在 75% 的页面中仅检查 Android 用户,可以看到 JS 长任务改进了 7%:
- 50% 用户的移动设备上的 JS Long Tasks 有 10% 的改进:
- 而对于 95% 用户,阻塞时间则减少了 10% :
“这些用户会遇到严重不利的网络和设备条件,每一次性能提升对他们来说尤其重要。”Matt 说道。
根据 Matt 说法,删除 jQuery 的本意是清理技术债。“它最初是为了支持浏览器而存在的,但随着时间的推移,情况发生了变化,所以 bits 可以被删除。我想在这之后会重新评估,看看还有什么是不再需要的。” Matt 表示。
jQuery 是一套跨浏览器的 JavaScript 库,可以简化 HTML 与 JavaScript 之间的操作。截至 2021 年,有将近 84% 的移动页面使用 jQuery。jQuery 是最受欢迎的 JavaScript 库之一,它的一些操作已经反映在标准 Web API 中。
JQuery 创建于 2006 年,主要是为了帮助开发者处理当时浏览器的不足。当时谷歌浏览器还未流行,人们饱受 Internet Explorer 之苦。而 JQuery 开发者可以使用 CSS 选择器和函数可以轻松地遍历和操作 DOM,
此外,JQuery 还提供了一些开箱即用的函数来做动画 DOM 元素,而无需弄乱 CSS。在没有 jQuery 之前发出 AJAX 请求很麻烦,但使用 JQuery 只需几行代码即可完成。JQuery 提供了一个可以在大多数浏览器上工作的 API,这在当时使用 JavaScript 是很难实现的。
但在过去的几年里,JavaScript 已经成熟了很多,它支持很多新的 API,其社区也构建了很多库来填补 jQuery 可能留下的任何空白。
现在,开发者几乎可以在原生 JavaScript 中做任何 jQuery 可以做的事情。例如,可以使用带有 querySelector 和 querySelectorAll 的 CSS 选择器语法来选择元素,使用 classList API 在元素上添加、删除和切换类,使用 addEventListener 将事件处理程序附加到 DOM 元素和窗口等等。
同时随着 Angular、Vue 和 React 等框架的出现和流行,一直未有特别创新的 jQuery 更显“老态”。“对我来说,他们 (jQuery ) 就像是那个随着时代变迁没有更新知识的老灰胡子。”有网友直言。
“现在,大多数事情都不再需要 jQuery 了。”有网友评论道,“我个人发现普通的 JS API 和 fetch 甚至比 jQuery 的东西更干净。人们仍然出于习惯使用 jQuery,是因为摆脱它需要做很多工作。”
近几年,业内对于“jQuery 是否已死”的讨论一直没停过。实际上,一些大型、资金充足的网站已经“用脚投票”,正在逐渐摆脱对 jQuery 的依赖。
2018 年,GitHub 宣布从 GitHub.com 的前端代码中完全移除了 jQuery。“早期,jQuery 对我们意义重大。”GitHub 前端工程团队在方式发布的文章里表示。“在 GitHub 的早期阶段,jQuery 让小型的开发团队能够快速进行原型设计并开发出新功能,而无需专门针对每个 Web 浏览器调整代码。”
但随着 GitHub 成长为一家拥有数百名工程师的公司,jQuery 带来的价值已经随着时间的推移而下降。比如技术债会随着依赖项的增多而增长,给企业带来很大的维护成本。因此,GitHub 最终决定删除 jQuery。不过,GitHub 没有选择另外的库或框架,而是使用标准的浏览器 API 来实现。
不只 GitHub,Bootstrap 最新版本也将删除 jQuery。
尽管被认为已经过时,但 jQuery 仍然是占主导地位的 JavaScript 库。今天的开发人员可能没有意识到在使用 jQuery,因为它被嵌入在了许多大型开源项目里面,其中最著名的就是 WordPress。
“大多数网站都不需要复杂的开发框架,它们大多是具有一些动态行为的静态网站,这种网站通常用 WordPress 编写。jQuery 在这个场景下仍然很流行,因为它既简单又有效,人们觉得没必要停止使用它。”jQuery 开发者 Micha Gobiowski-Owczarek 在接受外媒采访时说道。
Micha Gobiowski-Owczarek 也明确表示,为了不与浏览器冲突,jQuery 不会修改原生原型,而是用 jQuery 包装器对象包装 DOM 节点,每个操作都会创建一个新的包装器对象。大多数情况下,这并不重要,但对于具有大量 DOM 操作的、非常复杂的应用程序来说,可能会成为一个问题。
未来的很长一段时间里,jQuery 还继续会是 WordPress 的一部分,因为它很难在不破坏向后兼容性的情况下将它删除。但一些改变已经发生,如 WordPress 创建的 Gutenberg 编辑器不依赖于 jQuery。
随着时间的推移, WordPress 肯定会逐步更新技术,这是一个渐进的过程,jQuery 的最终去留也很难说。但不可否认的是,jQuery 为前端带来了重大的影响。
参考链接:
https://thenewstack.io/why-outdated-jquery-is-still-the-dominant-javascript-library/
jQuery选择器总结
jQuery 的选择器可谓之强大无比,这里简单地总结一下常用的元素查找方法
$(\”#myELement\”) 选择id值等于myElement的元素,id值不能重复在文档中只能有一个id值是myElement所以得到的是唯一的元素
$(\”div\”) 选择所有的div标签元素,返回div元素数组
$(\”.myClass\”) 选择使用myClass类的css的所有元素
$(\”*\”) 选择文档中的所有的元素,可以运用多种的选择方式进行联合选择:例如$(\”#myELement,div,.myclass\”)
层叠选择器:
$(\”form input\”) 选择所有的form元素中的input元素
$(\”#main > *\”) 选择id值为main的所有的子元素
$(\”label + input\”) 选择所有的label元素的下一个input元素节点,经测试选择器返回的是label标签后面直接跟一个input标签的所有input标签元素
$(\”#prev ~ div\”) 同胞选择器,该选择器返回的为id为prev的标签元素的所有的属于同一个父元素的div标签
基本过滤选择器:
$(\”tr:first\”) 选择所有tr元素的第一个
$(\”tr:last\”) 选择所有tr元素的最后一个
$(\”input:not(:checked) + span\”)
过滤掉:checked的选择器的所有的input元素
$(\”tr:even\”) 选择所有的tr元素的第0,2,4… …个元素(注意:因为所选择的多个元素时为数组,所以序号是从0开始)
$(\”tr:odd\”) 选择所有的tr元素的第1,3,5… …个元素
$(\”td:eq(2)\”) 选择所有的td元素中序号为2的那个td元素
$(\”td:gt(4)\”) 选择td元素中序号大于4的所有td元素
$(\”td:ll(4)\”) 选择td元素中序号小于4的所有的td元素
$(\”:header\”)
$(\”div:animated\”)
内容过滤选择器:
$(\”div:contains(\’John\’)\”) 选择所有div中含有John文本的元素
$(\”td:empty\”) 选择所有的为空(也不包括文本节点)的td元素的数组
$(\”div:has(p)\”) 选择所有含有p标签的div元素
$(\”td:parent\”) 选择所有的以td为父节点的元素数组
可视化过滤选择器:
$(\”div:hidden\”) 选择所有的被hidden的div元素
$(\”div:visible\”) 选择所有的可视化的div元素
属性过滤选择器:
$(\”div[id]\”) 选择所有含有id属性的div元素
$(\”input[name=\’newsletter\’]\”) 选择所有的name属性等于\’newsletter\’的input元素
$(\”input[name!=\’newsletter\’]\”) 选择所有的name属性不等于\’newsletter\’的input元素
$(\”input[name^=\’news\’]\”) 选择所有的name属性以\’news\’开头的input元素
$(\”input[name$=\’news\’]\”) 选择所有的name属性以\’news\’结尾的input元素
$(\”input[name*=\’man\’]\”) 选择所有的name属性包含\’news\’的input元素
$(\”input[id][name$=\’man\’]\”) 可以使用多个属性进行联合选择,该选择器是得到所有的含有id属性并且那么属性以man结尾的元素
子元素过滤选择器:
$(\”ul li:nth-child(2)\”),$(\”ul li:nth-child(odd)\”),$(\”ul li:nth-child(3n + 1)\”)
$(\”div span:first-child\”) 返回所有的div元素的第一个子节点的数组
$(\”div span:last-child\”) 返回所有的div元素的最后一个节点的数组
$(\”div button:only-child\”) 返回所有的div中只有唯一一个子节点的所有子节点的数组
表单元素选择器:
$(\”:input\”) 选择所有的表单输入元素,包括input, textarea, select 和 button
$(\”:text\”) 选择所有的text input元素
$(\”:password\”) 选择所有的password input元素
$(\”:radio\”) 选择所有的radio input元素
$(\”:checkbox\”) 选择所有的checkbox input元素
$(\”:submit\”) 选择所有的submit input元素
$(\”:image\”) 选择所有的image input元素
$(\”:reset\”) 选择所有的reset input元素
$(\”:button\”) 选择所有的button input元素
$(\”:file\”) 选择所有的file input元素
$(\”:hidden\”) 选择所有类型为hidden的input元素或表单的隐藏域
表单元素过滤选择器:
$(\”:enabled\”) 选择所有的可操作的表单元素
$(\”:disabled\”) 选择所有的不可操作的表单元素
$(\”:checked\”) 选择所有的被checked的表单元素
$(\”select option:selected\”) 选择所有的select 的子元素中被selected的元素
选取一个 name 为”S_03_22″的input text框的上一个td的text值
$(”input[@ name =S_03_22]“).parent().prev().text()
名字以”S_”开始,并且不是以”_R”结尾的
$(”input[@ name ^=\’S_\’]“).not(”[@ name $=\’_R\’]“)
一个名为 radio_01的radio所选的值
$(”input[@ name =radio_01][@checked]“).val();
$(\”A B\”) 查找A元素下面的所有子节点,包括非直接子节点
$(\”A>B\”) 查找A元素下面的直接子节点
$(\”A+B\”) 查找A元素后面的兄弟节点,包括非直接子节点
$(\”A~B\”) 查找A元素后面的兄弟节点,不包括非直接子节点
1. $(\”A B\”) 查找A元素下面的所有子节点,包括非直接子节点
例子:找到表单中所有的 input 元素
HTML 代码:
<form>
<label>Name:</label>
<input name=\”name\” />
<fieldset>
<label>Newsletter:</label>
<input name=\”newsletter\” />
</fieldset>
</form>
<input name=\”none\” />
jQuery 代码:
$(\”form input\”)
结果:
[ <input name=\”name\” />, <input name=\”newsletter\” /> ]
2. $(\”A>B\”) 查找A元素下面的直接子节点
例子:匹配表单中所有的子级input元素。
HTML 代码:
<form>
<label>Name:</label>
<input name=\”name\” />
<fieldset>
<label>Newsletter:</label>
<input name=\”newsletter\” />
</fieldset>
</form>
<input name=\”none\” />
jQuery 代码:
$(\”form > input\”)
结果:
[ <input name=\”name\” /> ]
3. $(\”A+B\”) 查找A元素后面的兄弟节点,包括非直接子节点
例子:匹配所有跟在 label 后面的 input 元素
HTML 代码:
<form>
<label>Name:</label>
<input name=\”name\” />
<fieldset>
<label>Newsletter:</label>
<input name=\”newsletter\” />
</fieldset>
</form>
<input name=\”none\” />
jQuery 代码:
$(\”label + input\”)
结果:
[ <input name=\”name\” />, <input name=\”newsletter\” /> ]
4. $(\”A~B\”) 查找A元素后面的兄弟节点,不包括非直接子节点
例子:找到所有与表单同辈的 input 元素
HTML 代码:
<form>
<label>Name:</label>
<input name=\”name\” />
<fieldset>
<label>Newsletter:</label>
<input name=\”newsletter\” />
</fieldset>
</form>
<input name=\”none\” />
jQuery 代码:
$(\”form ~ input\”)
结果:
[ <input name=\”none\” /> ]
本文作者及来源:Renderbus瑞云渲染农场https://www.renderbus.com
文章为作者独立观点不代本网立场,未经允许不得转载。