GitHub:https://github.com/nzbin/domq
文档:https://nzbin.gitbooks.io/domq-api/usage.html
jQuery 不会去世去从 GitHub 放弃 jQuery,再到 Bootstrap 5 宣告移除 jQuery,看来一个时期究竟要落下帷幕。
为什么我们会放弃 jQuery 呢?缘故原由无非这样几个:不须要再进行浏览器的兼容,原生 DOM 查找已经很方便,AJAX 要求有更好的替代办法等等。
在我看来 jQuery 最大的弊端是无法分模块引入,直接引入全体库实在有些欠妥,毕竟太多功能已经没有用武之地。但是 jQuery 的 DOM 操作依然很有必要。很多人对我的这个不雅观点有些疑问。其实在利用 MVVM 框架的时候,DOM 操作确实已经很少。但是我们也不可能总是做一些 CRUD 的功能。对付繁芜的业务需求仍旧须要一些 DOM 操作。
如果 jQuery 可以把 DOM 操作干系的功能模块分离出来,或许还有很大的利用空间。
原生当道
在平时的项目中,越来越多的人选择用原生 JS 去操为难刁难象,比如获取元素属性,宽高,定位等等。
早在几年前,github 上就有很多文章先容如何用原生 JS 代替 jQuery,比如 YouDontNeedJQuery,YouMightNotNeedjQuery等。就我个人而言,纯 JS 操作确实很大略,但是并不是很优雅,繁芜一点的操作还要常常翻 MDN。
// jQuery$('.my #awesome selector');// JSdocument.querySelectorAll('.my #awesome selector');// jQuery$(el).hide();// JSel.style.display = 'none';// jQuery$(el).after(htmlString);// JSel.insertAdjacentHTML('afterend', htmlString);
以上是 jQuery 和原生 JS 比拟的一个缩影,结果显而易见,jQuery 的 API 更加简洁。除此之外,jQuery API 的利用形式也非常统一。相反,原生 JS 的 API 利用办法就比较多样了,既有赋值,又有传参等。其余原生 JS 的 API 名称冗长,未便利影象。这也是很多 JS 库出身的意义。
很多插件一样平常都会有一个 utils 的文件,基本会对原生方法做一个大略封装并供应一些工具方法。
Zepto 的上风与弱势Zepto 是一个思想超前的库,为什么我会有这样的结论?Zepto 对原生方法做了进一步的抽象,利用更大略。正如我在上文说过的,既然 jQuery 的 API 简洁易用,而且我们也更加熟习,那我们为什么不将 jQuery 和原生 JS 结合起来呢?令人惊异的是,早在 2010 年,Zepto 的作者就已经这样去做了。用原生 JS 实现了 jQuery 的大部分 API,可替代率靠近九成吧,至少在我编写的插件中,险些可以更换掉所有的 jQuery API。而且 Zepto 也不是一味的利用 document.querySelector 方法,而是根据性能利害,有选择的利用 document.getElementById 以及 document.querySelector 等。
但是 Zepto 也有一些显而易见的毛病,毕竟还是上个时期的产物,首先便是无法按需加载,现在我们在写项目的时候更乐意根据自己的须要引入某些方法,而不是将全体库全部引入,虽然 Zepto 的体积不大,但是作为强制症还是有一些厌恶。其余便是 Zepto 本身也有一些 bug,比如 scrollTop、scrollLeft 方法。其它不同拜会源码。
// ZeptoscrollTop: function(value) { if (!this.length) return var hasScrollTop = 'scrollTop' in this[0] if (value === undefined) return hasScrollTop ? this[0].scrollTop : this[0].pageYOffset return this.each(hasScrollTop ? function() { this.scrollTop = value } : function() { this.scrollTo(this.scrollX, value) })}
document 元素无法得到精确的值,我对这个问题提过 pr 但是没有回应,Zepto 目前基本已经停滞掩护。精确的方法如下:
// Domqfunction scrollTop(value) { if (!this.length) return var hasScrollTop = 'scrollTop' in this[0] if (value === undefined) return hasScrollTop ? this[0].scrollTop : isWindow(this[0]) ? this[0].pageYOffset : this[0].defaultView.pageYOffset; return this.each(hasScrollTop ? function () { this.scrollTop = value } : function () { this.scrollTo(this.scrollX, value) })}Domq 的义务
形如 jQuery 的 DOM 操作库有很多,比如 bonzo、$dom,但是在我重构 jQuery 插件时,我创造没有办法用这些库直接更换 jQuery,只有 Zepto 相对完美,但是我又不肯望引入额外的无用的方法。
末了我决定改造 Zepto,使之更符合现在的利用习气。多说一点,个人以为 Zepto 的核心函数稍显缭乱,命名空间既有 zepto、又有 $、Z,觉得非常混乱,而 domq 的核心函数只有 D 这一个命名空间,形态及功能和 jQuery 的核心函数险些一样,可以认为是一个 mini 版的 jQuery。
// Zepto 核心方法var Zepto = (function() { var zepto = {}; ... zepto.Z = function(dom, selector) { return new Z(dom, selector) } ... $ = function(selector, context) { return zepto.init(selector, context) } ...})()// Domq 核心方法var D = function (selector, context) { return new D.fn.init(selector, context);}D.fn = D.prototype = { ... init: function(){ ... } ...}
当然, Domq 最关键的还是按需加载,根据须要挂载方法,只管即便减少不必要的代码。利用办法很大略,但是你须要创建一个独立文件,重新挂载须要的方法到 D 命名空间上,这在编写插件时非常有用。
import { D, isArray, addClass} from 'domq.js/src/domq.modular';// 静态方法const methods = { isArray}// 原型方法const fnMethods = { addClass}D.extend(methods);D.fn.extend(fnMethods);
其余,在做项目时常常会用到一些工具方法,这时候用一个工具库暴露这些方法或许是最好的办法。Domq 也有一些常用的工具方法,不过还须要再迭代一下。
D.type()D.contains()D.camelCase()D.isFunction()D.isWindow()D.isEmptyObject()D.isPlainObject()D.isNumeric()D.isArray()D.inArray()...安装
npm install domq.js --save
在 domq.js 的 dist 文件夹下有四个紧张文件
dist├── domq.js (UMD)├── domq.common.js (CJS)├── domq.esm.js (ESM)└── domq.modular.js (MODULAR)
默认加载模块化方案 domq.modular.js。
import { D } from 'domq.js'
或者根据须要加载指定文件
import { D } from 'domq.js/dist/domq.esm.js'模块化利用解释
按需加载须要手动将所需方法挂载到 D 函数上,示例如下:
import { D, isArray, addClass} from 'domq.js/src/domq.modular';// 静态方法const methods = { isArray}// 原型方法const fnMethods = { addClass}D.extend(methods);D.fn.extend(fnMethods);
Domq 没有太多新的东西,以是也没有太多可以先容的,它已经在插件 PhotoViewer 以及实际项目中得以利用,欢迎大家下载利用。
总结这是一个好的时期,也是一个坏的时期,jQuery 的落幕确实让人感叹,但是我们完备没必要由于 jQuery 的落幕而放弃 jQuery 的利用办法。正如前文所说,jQuery 的 DOM 操作在我看来依然是最好用的,以是,你不须要 jQuery,但你须要一个 DOM 库。