jQuery一鍵移除使前端項(xiàng)目脫離對它的依賴
前言
大家好,我是零一。雖然現(xiàn)在很多前端項(xiàng)目都在用Vue、React,但依賴jquery的項(xiàng)目也不少,尤其是年代比較久遠(yuǎn)的項(xiàng)目,那些還正在維護(hù)jquery項(xiàng)目的你,是否想將jquery從你的項(xiàng)目中移除?畢竟這個(gè)庫那么大,你能用到的代碼也就只有15%~30%,而且jquery對各個(gè)瀏覽器的兼容性也做了很大的處理(代碼量up up),但其實(shí)很多老項(xiàng)目也不會(huì)去考慮兼容很邊緣的瀏覽器了,所以其實(shí)jquery中兼容處理的代碼也沒太大必要
最近新發(fā)現(xiàn)了一個(gè)有意思的工具,僅上線2周,就有600+的Star,它說能幫助你的項(xiàng)目脫離對jquery的依賴,感覺是個(gè)不錯(cuò)的想法,一起來看看吧~
使用方式
這個(gè)工具的名字叫replace-jquery,據(jù)說是能幫你從項(xiàng)目中自動(dòng)查找所有用到的jquery方法,并生成一套原生js的方法去替代
先來搞一個(gè)極簡的jquery項(xiàng)目
index.html

main.js

測試一下頁面的功能,是OK的

接下來我們用 replace-jquery 工具試著移除一下 main.js 中的jquery代碼
先全局下載一下
npm install -g replace-jquery
然后在項(xiàng)目目錄使用,語法為
replace-jquery 目標(biāo)js文件 生成的js文件
replace-jquery main.js newMain.js
該工具會(huì)自動(dòng)找到你文件中所有用到的jquery方法。此處有一個(gè)確認(rèn)的步驟,你可以選擇想要替換哪些方法(默認(rèn)是全選的)

按回車鍵即可完成替換,并生成新的文件
export class Utils {
constructor(selector) {
this.elements = Utils.getSelector(selector);
this.element = this.get(0);
return this;
}
on(events, listener) {
events.split(' ').forEach((eventName) => {
this.each((el) => {
const tNEventName = Utils.setEventName(el, eventName);
if (!Array.isArray(Utils.eventListeners[tNEventName])) {
Utils.eventListeners[tNEventName] = [];
}
Utils.eventListeners[tNEventName].push(listener);
// https://github.com/microsoft/TypeScript/issues/28357
if (el) {
el.addEventListener(eventName.split('.')[0], listener);
}
});
});
return this;
}
remove() {
this.each((el) => {
el.parentNode.removeChild(el);
});
return this;
}
css(css, value) {
if (value !== undefined) {
this.each((el) => {
Utils.setCss(el, css, value);
});
return this;
}
if (typeof css === 'object') {
for (const property in css) {
if (Object.prototype.hasOwnProperty.call(css, property)) {
this.each((el) => {
Utils.setCss(el, property, css[property]);
});
}
}
return this;
}
const cssProp = Utils.camelCase(css);
const property = Utils.styleSupport(cssProp);
return getComputedStyle(this.element)[property];
}
static getSelector(selector, context) {
if (selector && typeof selector !== 'string') {
if (selector.length !== undefined) {
return selector;
}
return [selector];
}
context = context || document;
// For performance reasons, use getElementById
// eslint-disable-next-line no-control-regex
const idRegex = /^#(?:[\w-]|\\.|[^\x00-\xa0])*$/;
if (idRegex.test(selector)) {
const el = document.getElementById(selector.substring(1));
return el ? [el] : [];
}
return [].slice.call(context.querySelectorAll(selector) || []);
}
get(index) {
if (index !== undefined) {
return this.elements[index];
}
return this.elements;
}
each(func) {
if (!this.elements.length) {
return this;
}
this.elements.forEach((el, index) => {
func.call(el, el, index);
});
return this;
}
static setEventName(el, eventName) {
// Need to verify https://stackoverflow.com/questions/1915341/whats-wrong-with-adding-properties-to-dom-element-objects
const elementUUId = el.eventEmitterUUID;
const uuid = elementUUId || Utils.generateUUID();
// eslint-disable-next-line no-param-reassign
el.eventEmitterUUID = uuid;
return Utils.getEventName(eventName, uuid);
}
static setCss(el, prop, value) {
// prettier-ignore
let cssProperty = Utils.camelCase(prop);
cssProperty = Utils.styleSupport(cssProperty);
el.style[cssProperty] = value;
}
static camelCase(text) {
return text.replace(/-([a-z])/gi, (s, group1) => group1.toUpperCase());
}
static styleSupport(prop) {
let vendorProp;
let supportedProp;
const capProp = prop.charAt(0).toUpperCase() + prop.slice(1);
const prefixes = ['Moz', 'Webkit', 'O', 'ms'];
let div = document.createElement('div');
if (prop in div.style) {
supportedProp = prop;
} else {
for (let i = 0; i < prefixes.length; i++) {
vendorProp = prefixes[i] + capProp;
if (vendorProp in div.style) {
supportedProp = vendorProp;
break;
}
}
}
div = null;
return supportedProp;
}
static generateUUID() {
return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, (c) => {
// eslint-disable-next-line no-bitwise
const r = (Math.random() * 16) | 0;
// eslint-disable-next-line no-bitwise
const v = c === 'x' ? r : (r & 0x3) | 0x8;
return v.toString(16);
});
}
static getEventName(eventName, uuid) {
return `${eventName}__EVENT_EMITTER__${uuid}`;
}
}
Utils.eventListeners = {};
export default function $utils(selector) {
return new Utils(selector);
}
簡單看了一下,似乎就是把我們用到的jquery方法替換成了簡單的原生方法,并封裝在Utils這個(gè)類中,那么我們每次調(diào)用$("xxx")時(shí),其實(shí)就是在調(diào)用該類上的方法,那么對這個(gè)文件做一些修改
// 此處刪除export
class Utils {
// ...省略一些代碼
}
Utils.eventListeners = {};
// 此處刪除 export default,并將函數(shù)$utils改成$
function $(selector) {
return new Utils(selector);
}
這樣就相當(dāng)于我們在全局模擬jquery定義了一個(gè)$方法。此時(shí)html文件中的jquery引用就可以刪除了,并把我們剛才生成的文件引進(jìn)來

再去頁面中嘗試操作dom,可以看到效果跟之前一樣,成功!
補(bǔ)充
如果你想用該工具生成jquery所有api的替代文件,即生成一個(gè)super-mini-jquery,你可以這么做
replace-jquery --build-all super-mini-jquery.js
將代碼混淆丑化以后大概只有10kb

因?yàn)檫@個(gè)工具剛發(fā)布才2個(gè)星期不到,只實(shí)現(xiàn)了大部分的jquery代碼替換,比如ajax暫時(shí)是沒辦法替換的,你如果嘗試去替換,工具也會(huì)提醒你

總的來說,這個(gè)工具想法不錯(cuò),希望后期能支持更多的語法替換!
以上就是jQuery一鍵移除使項(xiàng)目脫離對它的依賴的詳細(xì)內(nèi)容,更多關(guān)于項(xiàng)目脫離jquery依賴的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
使用PHP+JQuery+Ajax分頁的實(shí)現(xiàn)
本篇文章小編將為大家介紹,使用PHP+JQuery+Ajax分頁的實(shí)現(xiàn)。需要的朋友參考下2013-04-04
用jQuery將JavaScript對象轉(zhuǎn)換為querystring查詢字符串的方法
這篇文章主要介紹了用jQuery將JavaScript對象轉(zhuǎn)換為querystring查詢字符串的方法,本文給大家分享兩種方法,非常不錯(cuò),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2018-11-11
基于JQuery的模擬蘋果桌面Dock效果(穩(wěn)定版)
之所以將它命名為穩(wěn)定版,是因?yàn)橹耙呀?jīng)分享了一個(gè)初級版本的,之前的初級版中存在很多bug?,F(xiàn)在經(jīng)過反復(fù)琢磨、實(shí)驗(yàn),修復(fù)了之前版本存在的很多不足之處,就算鼠標(biāo)快速的滑動(dòng)依然表現(xiàn)的很穩(wěn)定2012-10-10

