jQuery 插件
jQuery 之所以能统治 Web 十年,插件生态是关键推手——鼎盛时期有上万个插件,覆盖轮播、灯箱、表单校验、日期选择、拖拽排序……几乎所有常见交互都有现成插件。本章带你认识插件的本质、学会自己写一个,并了解在 React/Vue 时代怎么看待这套老生态。
1. 插件的本质:$.fn
jQuery 插件的核心机制简单到惊人:往 $.fn 上挂一个方法。$.fn 是 jQuery.prototype 的别名,所有 jQuery 对象共享原型,挂上去的方法所有选区都能调。
// jQuery 插件的本质:往 $.fn 上挂方法
// $.fn 是 jQuery.prototype 的别名,所有 jQuery 对象共享
// 最简单的插件:给所有元素加红框
$.fn.redFrame = function () {
// this 是当前 jQuery 对象(可能是多个元素)
this.css("border", "2px solid red");
return this; // 关键!返回 this 才能链式调用
};
// 使用
$("p").redFrame().addClass("framed");
// 注意:this 已经是 jQuery 对象,不用再 $(this) 包装
$.fn.logText = function () {
return this.each(function () { // 隐式迭代 + 维护链式
console.log($(this).text()); // each 回调里 this 才是 DOM
});
};两个关键点:插件函数里 this 已经是 jQuery 对象(不用 $(this) 包装),必须 return this(或 return this.each(...))才能维持链式调用。这是写插件的第一守则。
2. 经典插件模板
社区沉淀出了一套"标准插件模板":用 IIFE 包装(避免污染全局 + 把 $ 安全地别名化)、用 $.extend 合并默认参数、用 this.each 隐式迭代。背下来就能写出像样的插件。
// 经典插件模板(社区公认最佳实践)
(function ($) {
$.fn.highlight = function (options) {
// 1. 默认参数,与传入 options 合并
const settings = $.extend({
color: "yellow",
duration: 1000,
}, options);
// 2. 隐式迭代 + 维护链式
return this.each(function () {
const $el = $(this);
const originalBg = $el.css("background-color");
// 3. 插件逻辑
$el.css("background-color", settings.color);
setTimeout(function () {
$el.css("background-color", originalBg);
}, settings.duration);
});
};
})(jQuery); // 入参是 jQuery,内部用 $ 别名,避免冲突
// 使用
$("p").highlight(); // 用默认参数
$("p").highlight({ color: "lightblue", duration: 2000 }); // 自定义
$("p").highlight().addClass("done"); // 链式调用这个模板有三个亮点:IIFE 包装保证内部 $ 永远是 jQuery,即使外面用了 noConflict;$.extend 让插件可配置;return this.each 同时实现了"批量处理"和"链式调用"。
3. 支持方法的进阶插件
复杂插件(如 jQuery UI 的 datepicker)不止能初始化,还能调方法——datepicker("show")。这种插件用方法字典 + 字符串分发实现。
// 进阶:支持方法的插件(像 jQuery UI 的 .datepicker("show"))
(function ($) {
const methods = {
init: function (options) {
return this.each(function () {
const $el = $(this);
const settings = $.extend({
message: "Hello",
}, options);
$el.data("plugin", { settings: settings });
$el.text(settings.message);
});
},
show: function () {
return this.each(function () {
$(this).show();
});
},
hide: function () {
return this.each(function () {
$(this).hide();
});
},
destroy: function () {
return this.each(function () {
$(this).removeData("plugin").off(".myPlugin");
});
},
};
$.fn.greeter = function (methodOrOptions) {
if (methods[methodOrOptions]) {
return methods[methodOrOptions].apply(this, Array.prototype.slice.call(arguments, 1));
} else if (typeof methodOrOptions === "object" || !methodOrOptions) {
return methods.init.apply(this, arguments);
} else {
$.error("方法 " + methodOrOptions + " 在 greeter 上不存在");
}
};
})(jQuery);
// 使用
$("#box").greeter({ message: "你好" }); // 初始化
$("#box").greeter("hide"); // 调用方法
$("#box").greeter("destroy"); // 销毁这种模式让你写出 greeter 初始化、greeter("destroy") 销毁的 API——和官方插件风格一致。提供 destroy 方法是好插件的标准,让使用者能干净地释放资源。
4. 著名的 jQuery 插件生态
十年间涌现了无数经典插件,下面这些你大概率见过甚至用过:
// 著名的 jQuery 插件生态(鼎盛时期)
// 1. jQuery UI - 官方扩展,提供拖拽/排序/日期选择/对话框等
<script src="https://code.jquery.com/ui/1.13.2/jquery-ui.min.js"></script>
$("#dlg").dialog(); // 一行弹出对话框
$("#list").sortable(); // 列表可拖拽排序
$("#date").datepicker(); // 日期选择器
$("#tabs").tabs(); // Tab 选项卡
// 2. Slick - 最流行的轮播图插件
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/slick-carousel@1.8.1/slick/slick.min.css" />
<script src="https://cdn.jsdelivr.net/npm/slick-carousel@1.8.1/slick/slick.min.js"></script>
$(".slider").slick({
autoplay: true,
dots: true,
arrows: true,
});
// 3. Lightbox / Fancybox - 图片灯箱
<a class="lightbox" href="big.jpg"><img src="thumb.jpg" /></a>
$(".lightbox").lightbox();
// 4. Select2 / Chosen - 美化下拉框
$("select").select2();
// 5. jQuery Validate - 表单校验(至今最常用)
$("form").validate({
rules: { email: { required: true, email: true } },
messages: { email: { required: "请填邮箱" } },
});即使在新项目里,jQuery Validate(表单校验)和 Select2(美化下拉框)仍是不少团队的默认选择——它们专注、稳定、文档完善,比很多"现代替代品"更省心。维护老代码时,认得这些名字就能快速定位。
5. 现代项目里怎么对待 jQuery 插件
新项目还要不要用 jQuery 插件?答案是看场景:
// 现代项目里 jQuery 插件怎么处理?
// 1. 老项目维护:照常用
// WordPress / 老企业系统 仍依赖 jQuery 插件
// Bootstrap 4 及以前 用 jQuery + Popper.js
// 2. 新项目替代方案
`jQuery UI 拖拽` → SortableJS / react-dnd / @dnd-kit
`jQuery Validate` → zod / yup / ajv / HTML5 原生校验
`Slick 轮播` → Swiper / embla-carousel
`Lightbox` → photoswipe / glightbox
`Select2` → Choices.js / Tom Select
`DatePicker` → flatpickr / pikaday
// 3. 给现代框架写"插件"的思路
// React: 自定义 Hook + 组件,而非扩展 React 对象
// Vue: app.use(plugin) / 组合式函数
// 这些都基于"组件 + 数据驱动",而非 jQuery 的"扩展原型"
// 4. 哪些场景 jQuery 插件仍是合理选择?
// - 老项目维护(改造成本太高)
// - 简单营销页/官网(引个 jQuery 比配 React 构建快)
// - 嵌入第三方系统(CMS / LMS / 邮件模板编辑器)
// - 内部工具脚本(一次性、不需长期维护)核心判断标准:项目生命周期 + 团队技术栈 + 维护成本。短期营销页、老项目维护、嵌入 CMS——jQuery 插件仍是合理选择;长期维护的产品代码、技术栈已用 React/Vue——优先找现代替代品。别为了"现代化"而强行重写老代码,成本收益常常不划算。
6. 写插件的几条忠告
如果真的要写 jQuery 插件(维护老项目或简单页面),记住这几条经验:
- 始终 return this:让插件支持链式调用,这是 jQuery 文化。
- 用 IIFE 包起来:避免污染全局,别名化
$。 - 只暴露一个名字空间:所有方法挂在
$.fn.yourPlugin下,避免起一堆全局函数。 - 提供默认参数 + extend:让插件"开箱即用"又"深度可配"。
- 提供 destroy 方法:让使用者能干净地卸载,释放事件监听。
- 不要假设环境:检查依赖、处理元素不存在的情况,
this.each对空选区也安全。 - 命名空间事件:用
.on("click.myPlugin"),避免和用户其他代码冲突。
系列总结
恭喜你走到了 jQuery 系列的最后一篇。回顾一下学过的:
- 第 1 篇 历史:理解 jQuery 为何诞生,它的"抹平浏览器差异"使命。
- 第 2 篇 引入:CDN / 本地 / npm 三种方式,能接到任何项目。
- 第 3 篇 选择器:CSS 选择器 + jQuery 过滤器,选中任意元素。
- 第 4 篇 事件:
on统一 API + 事件委托处理动态元素。 - 第 5 篇 DOM:
text/html/val/attr/css/addClass取赋改元素。 - 第 6 篇 动画:基础
show/hide+ 滑动 + 淡入 +animate。 - 第 7 篇 AJAX:
get/post/ajax+ Promise + 表单序列化。 - 第 8 篇 链式:返回 this +
end/addBack选区栈。 - 第 9 篇 插件:
$.fn扩展 + 模板 + 著名生态。
jQuery 是一座历史桥梁——理解它,你就理解了过去十年 Web 是怎么走过来的;会读它,你就能维护互联网上过半的存量代码。下一步可以去看看 Bootstrap 教程——它和 jQuery 是同代搭档,至今仍是快速建站利器。
← 上一篇 jQuery 链式调用
← 返回 jQuery 教程目录