jQuery UI 的部件工厂
更新日期:
用 jQuery 编写第三方插件,常见的三种方式:
- 新的全局函数 $.xxx()
- jQuery 的对象方法 $(‘div’).xxx()
- jQuery UI 的部件工厂:少量编码,复杂插件
前两种方式在上节 《用 jQuery 编写第三方插件》 中有介绍到,本节重点关注第3点:jQuery UI 的部件工厂。
简介
jQuery UI 提供了一套部件。部件本身就是插件,只不过是用来生成特定的 UI 元素,它有一组非常统一的 API。如果我们想要编写自己的插件,且该插件会创建新的用户界面元素,那么此时,最好是以扩展 jQuery UI 库的方式来实现。
jQuery UI 库的核心包含了一个工厂方法 $.widget(),这个方法为我们做了很多事情,以确保我们的代码达到所有 jQuery UI 部件共享的 API 标准。 使用部件工厂创建的插件,自带以下功能,包括但不限于:
1.插件具有的状态:可以检测、修改,甚至在应用之后完全颠覆插件的原始效果
2.自动将用户提供的选项和定制的选项合并到一起
3.多个插件方法无缝组合成一个 jQuery 方法,这个方法接受一个表明要调用哪个子方法的字符串
4.插件触发的自定义事件处理程序,可以访问部件实例的数据
举例说明
在本小节中,我们通过代码实例,来认识下 jQuery UI 部件的相关特性:
1.通过部件工厂创建插件 $.widget()
2.插件的初始化函数 _create()
3.触发插件的元素:引用、绑定事件
4.部件选项:默认、接收、覆盖
5.插件状态:启用&禁用、销毁插件
6.触发部件事件
7.添加插件的方法:私有方法、公有方法
首先,要在页面里引用这三个 js:jquery、jquery.ui.core 和 jquery.ui.widget,因为 jQuery UI 依赖于它们
|
|
现在,我们要实现一个为元素添加自定义提示条的 UI 插件。待完成的是功能是:
1.为元素创建一个div容器
2.当鼠标悬停在该元素上时,把这个容器放在相应元素的旁边。
代码如下:
|
|
使用插件时:
|
|
接下来,我们来逐个认识下代码中的相关知识点:
$.widget()
通过部件工厂创建插件,它接收两个参数:
- 部件的名字,即”ljq.tooltip”:部件的名字必须带有命名空间,此例中”ljq”是命名空间,”tooltip”是插件名
使用时,直接在 jQuery 对象上调用 .tooltip(),和插件的名字保持一致。 - 部件属性的映射:它可以是选项对象,也可以是函数。当函数名以下划线_开头时,代表是私有函数。否则是公有函数
_create()
_create() 是个特殊的函数,每当 jQuery 对象中每个匹配的元素调用 .tooltip() 时,部件工厂就会调用它。
this.element 和 绑定事件
this.element 存了一个 jQuery 对象,这个对象指向最初选择的元素,我们用 this.element 给提示条的触发元素绑定事件。
绑定事件时,事件名也要加上和插件名一样的命名空间前缀,即 “mouseenter.ljq-tooltip”。此处,把处理程序传递给 $.proxy(this._open, this),这个函数会修改 this 的指向,因此才能在 _open 函数中引用部件的实例。
接受部件选项
让部件可定制:在之前介绍的 .shadow() 插件中,我们已经为部件提供了一组定制的默认值,用户也可以用指定的选项去覆盖默认值。在这里呢,我们可以“清闲”点不用那么麻烦,因为几乎所有的工作都是由部件工厂执行的,我们要做的就是:提供一个 options 属性。
options 属性是一个映射,包括插件所需的所有选项,这样用户就可以不用提供了-直接用默认值即可。在插件内的子方法中,可以通过 this.options 来访问这些选项。而且,通过这种方式访问选项,始终都能保证取得的是正确的值-即要么是默认,要么是用户提供的覆盖了默认值。
启用和禁用插件
插件,除了被完全销毁外,还可以临时禁用-然后在将来重新启用部件。内置的 enable 和 disable 子方法,可以帮助我们实现部件的启用和禁用,即 .tooltip(‘enable’) 和 .tooltip(‘disable’)。它们是分别给 this.options.disabled 赋了不同的值,即 this.options.disabled = true|false; 要支持这两个子方法,我们只需要做:对部件进行任何操作前,先检查这个值,就 ok 了。
触发部件事件
真正的好插件,除了自己可以扩展 jQuery 外,还可以为其他代码提供机制来扩展它。提供这种扩展能力的方法之一,就是:支持与插件相关的一组自定义事件。
this._trigger(‘open’) 可以让代码监听新的自定义事件,在这个元素上调用 .bind(‘tooltipopen’) 就可以监听这个事件。监听时的事件命名是”部件名字+事件名字”,所以不会与外界的事件名冲突。
销毁部件
部件工厂可以创建新的 jQuery 方法,上面的代码就创建了 .tooltip()。可以给这个方法传入一个字符串参数,就可以调用适当的子方法了。其中,销毁部件的内置子方法是 destroy,所以,调用 .tooltip(‘destroy’) 就可以从页面中删除这个提示条部件,部件工厂为我们做了很多工作。
但,如果我们通过 _create() 修改了文档(即创建了新的div),那么在销毁之前,我们自己要负责将其清理掉。然后再调用保存在原型对象中的 destory,便会自动完成清理工作。
公共子方法
创建私有函数,函数名以下划线开头,即可
创建公有函数,函数名不以下划线开头,即可
在公有函数(即子方法)里,里面什么都不返回,部件工厂也会默默地做好多工作,从而确保连缀语法可以正常工作。比如,我们可以这样使用 .tooltip(‘open’) .tooltip(‘close’)
others
1.this:在部件内部的上下文中,this 引用当前部件实例,可以用它来为部件添加任何想要的属性
2.部件实例本身,也有一些预定义的属性可供我们使用。比如 this.options、this.options.disabled、this.element 等
这个插件本身不复杂,代码也不长。但它却浓缩了很多高级概念。
QA
??
每个部件都有哪些复杂性
jQuery UI 库都有什么必须的共享API标准
触发部件事件,它的应用场景是啥,意思是:_trigger()了之后 才能那么bind么?
this.options.content.call(this.element[0])
this.element “最初选择的元素”还是触发提示条的那个元素么…如果是.find().find()
?为何不链式调用.show呢?是考虑到上面操作了css和text-生效后才show?or 笔误?
那个…
事实上,这个功能很诱人,在构建任何适当的(无论是否与UI相关)复杂插件,谁都希望使用部件工厂的方法。“都希望” 是么?但它又需要额外引入 jquery.ui.core 和 jquery.ui.widget 呢…感觉这两种不同的创建插件的方法,各有自己的适用场景吧。自己抽取几个实战感受下。
链式调用棒棒哒
公用的方法不用返回什么 就自动连缀。【果然做了挺多的】