jQuery UI 部件库(Widget Factory)

jQuery UI 部件库(Widget Factory)

Widget Factory(部件工厂)是 jQuery UI 最核心、最重要的贡献。它是一个强大的插件开发框架,暴露为 $.widget() 方法,所有 jQuery UI 官方小部件(如 Datepicker、Tabs、Dialog、Accordion、Slider 等)都是基于它构建的。

Widget Factory 的设计目标是解决传统 jQuery 插件的常见痛点,提供一套标准化、状态化、可继承、可扩展的插件开发模式。

官方文档地址:https://api.jqueryui.com/jQuery.widget/

为什么需要 Widget Factory?

普通 jQuery 插件通常存在以下问题:

  • 没有统一 API(初始化、方法调用、选项设置方式各不相同)。
  • 难以维护内部状态(例如进度条的当前值)。
  • 事件命名不一致。
  • 难以继承和扩展。
  • 销毁时清理不彻底。

Widget Factory 完美解决了这些问题,让所有插件拥有统一的生命周期和 API。

核心特性

  1. 统一 API 模式
   // 初始化
   $("#elem").myWidget({ option1: value });

   // 调用方法
   $("#elem").myWidget("methodName", arg);

   // 设置/获取选项
   $("#elem").myWidget("option", "key", value);
   var val = $("#elem").myWidget("option", "key");

   // 销毁
   $("#elem").myWidget("destroy");
  1. 生命周期钩子
  • _create():首次创建时调用(相当于构造函数)。
  • _init():每次初始化(包括重新初始化)时调用。
  • _setOption(key, value):选项改变时自动调用。
  • _destroy():销毁时自动调用,用于清理事件、DOM 修改。
  1. 状态管理
  • 实例数据存储在元素的 jQuery data 中:this.element.data("ui-myWidget", this)
  • 支持启用/禁用:enable() / disable()
  1. 事件系统
  • 使用 _trigger("eventName", event, data) 触发自定义事件。
  • 用户可绑定:$("#elem").on("mywidgetchange", handler)
  1. 继承支持
  • 支持单继承,便于扩展现有部件。

创建自定义部件示例

// 定义一个简单的进度条部件(简化版)
$.widget("custom.progress", {
    // 默认选项
    options: {
        value: 0,
        max: 100
    },

    // 创建时调用
    _create: function() {
        this.element.addClass("custom-progress ui-widget ui-widget-content ui-corner-all");

        this.progressBar = $("<div>")
            .addClass("custom-progress-value ui-widget-header ui-corner-all")
            .appendTo(this.element);

        this._refreshValue();
    },

    // 选项改变时调用
    _setOption: function(key, value) {
        this._super(key, value);  // 调用父类方法
        if (key === "value") {
            this._refreshValue();
        }
    },

    // 自定义方法:获取/设置值
    value: function(newValue) {
        if (newValue === undefined) {
            return this.options.value;
        }
        this.option("value", newValue);
    },

    // 刷新 UI
    _refreshValue: function() {
        var percentage = (this.options.value / this.options.max) * 100;
        this.progressBar.width(percentage + "%");

        // 触发 change 事件
        this._trigger("change", null, { value: this.options.value });
    },

    // 销毁时清理
    _destroy: function() {
        this.element.removeClass("custom-progress ui-widget ui-widget-content ui-corner-all")
                    .empty();
    }
});

使用自定义部件

<div id="myProgress"></div>

<script>
$(function() {
    $("#myProgress").customProgress({ value: 30 });

    // 绑定事件
    $("#myProgress").on("customprogresschange", function(event, ui) {
        console.log("当前值:", ui.value);
    });

    // 改变值
    setTimeout(function() {
        $("#myProgress").customProgress("value", 70);
    }, 2000);
});
</script>

继承现有部件示例

// 扩展 Dialog,添加自定义标题图标
$.widget("custom.iconDialog", $.ui.dialog, {
    options: {
        icon: "ui-icon-info"
    },

    _create: function() {
        this._super();  // 调用父类 _create

        if (this.options.icon) {
            this.uiDialogTitlebar.prepend(
                $("<span>").addClass("ui-dialog-title-icon " + this.options.icon)
            );
        }
    }
});

总结

  • Widget Factory 是 jQuery UI 最有价值的遗产之一。
  • 它让插件开发变得规范、可维护、可扩展。
  • 所有官方部件(如 dialog、tabs、datepicker)都继承自它,因此行为高度一致。
  • 即使 jQuery UI 项目进入维护模式,Widget Factory 依然是学习插件开发的最佳范例。

如果您想查看某个官方部件(如 Datepicker)的源码实现细节,或需要帮助创建特定功能的自定义部件,欢迎继续提问!

文章已创建 4298

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

相关文章

开始在上面输入您的搜索词,然后按回车进行搜索。按ESC取消。

返回顶部