jQuery UI 自定义组件
使用 Widget Factory 创建 jQuery UI 组件
问题
如何使用 jQuery UI 的 Widget Factory 创建自定义组件?
解答
jQuery UI 提供了 $.widget() 方法来创建可复用的组件,它封装了状态管理、方法调用、事件触发等通用逻辑。
基本结构
$.widget("namespace.widgetName", {
// 默认配置
options: {
option1: "default"
},
// 组件创建时调用
_create: function() {},
// 组件销毁时调用
_destroy: function() {},
// 配置项变更时调用
_setOption: function(key, value) {}
});
完整示例:计数器组件
// 定义计数器组件
$.widget("custom.counter", {
// 默认配置
options: {
value: 0,
min: 0,
max: 100,
step: 1
},
// 组件初始化
_create: function() {
// 添加样式类
this.element.addClass("ui-counter");
// 创建 DOM 结构
this._buildUI();
// 绑定事件
this._bindEvents();
// 设置初始值
this._updateDisplay();
},
// 构建 UI
_buildUI: function() {
this.decrementBtn = $("<button>")
.text("-")
.addClass("ui-counter-btn")
.appendTo(this.element);
this.display = $("<span>")
.addClass("ui-counter-display")
.appendTo(this.element);
this.incrementBtn = $("<button>")
.text("+")
.addClass("ui-counter-btn")
.appendTo(this.element);
},
// 绑定事件
_bindEvents: function() {
var self = this;
this.decrementBtn.on("click", function() {
self.decrement();
});
this.incrementBtn.on("click", function() {
self.increment();
});
},
// 更新显示
_updateDisplay: function() {
this.display.text(this.options.value);
},
// 公共方法:增加
increment: function() {
var newValue = this.options.value + this.options.step;
if (newValue <= this.options.max) {
this._setValue(newValue);
}
},
// 公共方法:减少
decrement: function() {
var newValue = this.options.value - this.options.step;
if (newValue >= this.options.min) {
this._setValue(newValue);
}
},
// 设置值并触发事件
_setValue: function(value) {
var oldValue = this.options.value;
this.options.value = value;
this._updateDisplay();
// 触发自定义事件
this._trigger("change", null, {
oldValue: oldValue,
newValue: value
});
},
// 处理配置项变更
_setOption: function(key, value) {
// 调用父类方法
this._super(key, value);
if (key === "value") {
this._updateDisplay();
}
},
// 组件销毁
_destroy: function() {
this.element
.removeClass("ui-counter")
.empty();
}
});
使用组件
// 初始化
$("#myCounter").counter({
value: 10,
max: 50,
step: 5
});
// 调用方法
$("#myCounter").counter("increment");
$("#myCounter").counter("decrement");
// 获取/设置配置
var value = $("#myCounter").counter("option", "value");
$("#myCounter").counter("option", "value", 20);
// 监听事件
$("#myCounter").on("counterchange", function(event, data) {
console.log("值从", data.oldValue, "变为", data.newValue);
});
// 销毁组件
$("#myCounter").counter("destroy");
组件继承
// 继承已有组件
$.widget("custom.superCounter", $.custom.counter, {
options: {
showReset: true
},
_buildUI: function() {
// 调用父类方法
this._super();
// 添加重置按钮
if (this.options.showReset) {
this.resetBtn = $("<button>")
.text("重置")
.on("click", $.proxy(this.reset, this))
.appendTo(this.element);
}
},
reset: function() {
this._setValue(0);
}
});
关键点
$.widget()第一个参数是namespace.name格式,命名空间避免冲突_create是初始化入口,_destroy负责清理- 以
_开头的方法是私有方法,不能通过$(el).widget("_method")调用 this.element是 jQuery 对象,指向组件绑定的 DOM 元素_trigger触发的事件名会自动加上组件名前缀(如counterchange)_setOption和_setOptions用于响应配置变更,记得调用this._super()
目录