轻剑用到顺手处,招式便想自己创。jQuery 的一大好处就在这儿:
你写好的动作,可以收进 $.fn 里,从此变成人人可用的新招式——这就是插件。
- 插件就是挂在
$.fn上的方法:$('#x').你的方法() - 用
$.fn.extend一次注册多个方法,记得return this保住链式 - 用
$.extend合并默认选项,让插件可配置 - 用
$.extend扩展全局工具函数($.你的工具()) - 接第三方插件前先问三件事:加载顺序、依赖、能否离线
插件长什么样
jQuery 对象身上的所有方法都存在 $.fn(其实就是
$.prototype 的别名)里。$.fn.addClass、$.fn.fadeIn
都是挂上去的方法——所以你往 $.fn 上再挂一个函数,就造出了新招式:
三步走:给 $.fn 加方法 → 在方法里操作 this → 返回 this。
“返回 this”不是客套,而是让后续方法还能接着点——插件若忘了它,
$('#title').hello().addClass(...) 会在中间断掉。
修行语录:日拱一卒、功不唐捐。
注意调用那一行:.highlight().addClass('fw-bold')——插件返回了
this,所以 addClass 还能接上。这就是“保住链式”的实惠。
带选项的插件:默认值 + 用户值
好用的插件都带设置项。标准做法是先立一份默认选项,再用
$.extend 把用户传进来的覆盖上去。这样调用者可以只写关心的一两项,
其余走默认值:
这里多了两件宝贝:其一,var settings = $.extend(默认, options);
其二,return this.each(function () { … })——each
会遍历选中的每一个元素,让插件对一批元素逐个生效。这是 jQuery 插件的经典模板,
背下来也不亏。
- 晨练站桩
- 临帖一页
- 读文档半小时
扩展全局工具:$.extend 的另一种用法
给 $.fn 加方法,得到的是“元素身上的招式”;
给 $ 本身加方法(用 $.extend({...})),得到的是
“不依赖元素的小工具”,用法类似上一式的 $.map:
点按钮,看自造工具的结果。
用别人的插件:先问三件事
- 顺序:插件文件必须排在 jQuery 之后,否则它找不到
$可挂; - 依赖:有些插件还要 Popper、Moment 之类的伙伴,缺一个就罢工;
- 离线:把插件文件下载到本地、放进自己的 js 目录——本站不引用任何 CDN, 你的项目也不必。
用第三方插件前,先读它调用的那几行 API(通常就是 $(选择器).插件名({选项}));
用久了自己写的插件,也要遵守同样的规矩:命名带前缀、选项有默认值、
方法返回 this。前人立约,后人省事——这就是为什么 jQuery 生态里
几十万个插件能彼此相安无事。
- 写一个插件
$.fn.flash():先fadeOut(200)再fadeIn(200), 并保证返回this。 - 给例 2 的
tagIt插件加一个size选项(例如'sm'/''), 控制徽章大小(提示:badge没有尺寸类,可改用fs-6之类的字号类)。 - 思考题:为什么插件里不能直接用
settings这个变量名存“每次调用”的设置, 而要先var settings = $.extend(…)?
参考答案 1
fadeOut 本身返回 this,所以直接用它的返回值即可;
但“显式写一个 return this”是更稳的习惯——将来改动内部实现时,
不会不小心把链式弄断。
参考答案 2
新选项写进默认值对象后,调用者不传就照旧,传了就生效——
插件的选项表就这样一点点长出来。真实项目里,还会把默认值暴露成
$.fn.tagIt.defaults,方便全局改。
参考答案 3
因为插件方法可能被调用很多次,每次的选项都不同。settings 若是插件外的
“共享变量”,第二次调用就会覆盖第一次的值,先前的元素也会跟着变——
典型的“一个变量管两家事”。写成 var settings = $.extend(默认, options),
每次调用都得到属于自己的那一份设置,互不干扰。
这也是上一式“深合并时传空对象当目标”的同一个道理:别把别人的默认值改了。
本式小结
- 插件 = 挂在
$.fn上的方法,模板是“合并选项 →this.each(操作)→return this”; $.fn.extend一次注册多个方法,$.extend扩展全局工具;- 默认选项用
$.extend合并,调用者只用写与默认不同的部分; - 接第三方插件先看顺序、依赖与离线,再谈好不好用;
- 插件的分寸感:做一件事、名字带前缀、永远把 jQuery 对象还回去。
下一式,我们说说“快”——不是招式快,而是让招式少费力气:性能心法。