插件可以让你无侵入地为衍生自Base类的宿主对象(称为host的对象)添加对象。如Node、Widget等类的对象实例。
可以通过继承Plugin.Base类来创建插件类。除此之外还可以通过后面的其他方法创建插件。
在Base类中已经介绍可以通过插件向组件实例添加功能,组件类甚至可以对插件功能一无所知。这样我们就可以在组件实例级别使用这些功能,
从而避免了为了添加这些功能而把组件类构造得很大或者构建多个不同的组件类。
1创建简单插件
对于简单的插件,如果不需要定义自己的事件和属性、不需要监听宿主的事件来改变宿主的行为、不需要重写宿主的方法的话,插件类可以只是简单的JavaScript类。
插件类唯一需要的是添加用作名称空间的静态属性“NS”,作为通过宿主实例对象来访问插件实例。
当插件被插入到宿主实例中后,插件实例就会被创建。宿主实例引用会作为参数传入到插件的构造器中,这样插件实例就可以获取宿主对象的引用。
当插件从宿主对象中拔出后,插件实例就被销毁。
//这个AnchorPlugin插件被设计成Node实例的插件 (宿主是Node实例) function AnchorPlugin(config) { // 存放宿主实例(Node实例)的引用,以便插件的其他方法使用。 this._node = config.host; } // 被插入到Node实例后,通过Node实例的"anchors"属性可以访问到插件 AnchorPlugin.NS = "anchors" AnchorPlugin.prototype = { disable: function() { var node = this._node;//引用的宿主对象 var anchors = node.all("a"); anchors.addClass("disabled"); anchors.setAttribute("disabled", true); } }; //为Node实例增加插件功能 var container = Y.one("div.actions"); container.plug(AnchorPlugin); //根据插件NS属性的值,可以通过Node实例访问插件实例 container.anchors.disable();
YUI框架中的插件,如Y.Plugin.Drop,Y.Plugin.NodeFX等,并不是需要提供监听和方法注入的功能,在实现中,只是extend Y.DD.Drop,Y.Anim.具体可参考其源代码。
对于需要在原始对象已有方法上扩展新的功能(如在widget调用hide时,增加动画效果插件)则需要利用下面介绍的Plugin.Base的生命周期管理和host方法注入功能。
2高级插件类
上述简单插件类可以满足简单的功能。但是当你想在插件类中实现更复杂的功能时,插件类如果支持attributes和events的能力就会非常的有用。
更重要的是,对于很多插件来说要修改宿主实例的默认行为。(比如一个Animation插件需要修改Widget类的show/hide行为)
对于这些需要丰富功能的插件,需要继承插件的基类Plugin.Base。
Plugin.Base是Base的子类,一次也支持attribute属性维护、生命周期方法及自定义事件。此外,我们可以在插件类中监听宿主实例触发的事件,或者在宿主某个方法执行
前/后,注入插件的自定义逻辑代码(基于YUI3的AOP基础结构)。Plugin.Base还定义了host属性,可以在插件中调用this.get(’host')获取宿主实例引用。
2.1扩展Plugin.Base
继承Plugin.Base可以像继承Base一样,需要注意的一点是,与简单插件相比,继承字Plugin.Base的插件,宿主实例会自动设置为插件的host属性。而简单的插件需要手动通过构造器将宿主实例传入插件实例并设置为属性才能访问。
继承自Plugin.Base的插件与继承自Base的子类是一样的,只不过是多个静态属性NS。
//一个为Widget的show/hide方法设置的动画插件 function WidgetAnimPlugin(config) { WidgetAnimPlugin.superclass.constructor.apply(this, arguments); } //定义NAME和NS静态属性 WidgetAnimPlugin.NAME = 'widgetAnimPlugin'; WidgetAnimPlugin.NS = 'fx'; //为插件定义自定义属性 WidgetAnimPlugin.ATTRS = { animHidden : { ... }, animVisible: { ... } }; // 继承 Plugin.Base Y.extend(WidgetAnimPlugin, Y.Plugin.Base, { // 添加需要的原型方法 });
YUI3为我们提供 了插件模版文件,我们可以使用它作为创建Plugin.Base类的良好的开始。
2.2Plugin的监听器
扩展Plugin.Base类最大的好处是可以使用Plugin.Base提供的onHostEvent和afterHostEvent方法来改变宿主实例事件触发时的行为,
还可以通过beforeHostMethod和afterHostMethod方法来改变宿主实例的方法。 (此外Plugin.Base还提供了doBefore和doAfter方法,既可以监听事件,又可以改变方法。)
通过Plugin.Base类提供的这些方法来改变宿主实例默认行为,而不是通过修改宿主类来实现的好处是:通过插入的方式修改了对象方法在
拔出以后,对象方法会被还原。
事件
上面提到过,对于继承自Plugin.Base类的插件,可以监听宿主对象的事件,修改它们的行为。
比如,当widget被渲染的时候会触发render事件,插件可能需要知道这个事件什么时候发生,可以在宿主渲染的时候插入一些自定义的html片段。这就可以使用afterHostEvent方法来实现:
// 一个为widget创建圆角边框的插件 function RoundedCornersPlugin(config) { //... } RoundedCornersPlugin.NAME = 'roundedCornersPlugin'; RoundedCornersPlugin.NS = 'corners'; Y.extend(RoundedCornersPlugin, Y.Plugin.Base, { // 该方法会在Base的构造器方法中自动调用 initializer: function(config) { // "render" 是widget的事件 this.afterHostEvent('render', this.insertCornerElements); }, insertCornerElements: function() { var widget = this.get("host"); var boundingBox = widget.get("boundingBox"); var tl = Y.Node.create(TL_TEMPLATE); //... boundingBox.appendChild(tlNode); boundingBox.appendChild(trNode); boundingBox.appendChild(blNode); boundingBox.appendChild(brNode); } });
方法
在某些情况下,插件需要覆盖宿主实例的一些方法。Plugin.Base提供的beforeHostMethod和afterHostMethod方法可以在宿主实例方法执行前后插入自定义的逻辑代码。
比如,为Widget实例的show和hide方法添加动画,可以通过覆盖控制widget boundingBox容器visibility样式的方法,添加修改透明度的动画来实现。
//一个为Widget的show/hide方法设置的动画插件 function WidgetAnimPlugin(config) { //... } WidgetAnimPlugin.NAME = 'widgetAnimPlugin'; WidgetAnimPlugin.NS = 'fx'; WidgetAnimPlugin.ATTRS = { animHidden : { //... }, animVisible: { //... } }; // 扩展Plugin.Base 重载默认的改变显示状态的方法_uiSetVisible 。 Y.extend(WidgetAnimPlugin, Y.Plugin.Base, { initializer : function(config) { // 在_uiSetVisible调用前调用_uiAnimSetVisible方法 this.beforeHostMethod("_uiSetVisible", this._uiAnimSetVisible); }, _uiAnimSetVisible : function(show) { if (this.get("host").get("rendered")) { if (show) { this.get("animHidden").stop(); this.get("animVisible").run(); } else { this.get("animVisible").stop(); this.get("animHidden").run(); } // 阻止默认方法执行。 return new Y.Do.Prevent(‘AnimPlugin prevented default show/hide’); } } });
关于完整的 WidgetAnimPlugin例子,请访问YUI Plugin官方例子。
相关推荐
标题中的"struts2 yahoo yui ajax plugin"指的是一个特定的插件,这个插件将Yahoo YUI库与Struts2框架整合,以支持使用Ajax技术进行异步数据交互。这个插件允许开发者利用YUI的强大的JavaScript功能来增强Struts2...
【压缩包子文件的文件名称列表】"minify-maven-plugin-master" "minify-maven-plugin.zip"是一个Maven插件,它的目标是合并和压缩JavaScript和CSS文件,以提高网页加载速度。Maven是一个广泛使用的Java项目管理和...
- **技术栈成熟**:使用当前最主流的J2EE开发框架和技术,易于学习和维护。 - **数据库支持广泛**:支持多种数据库,如MySQL、Oracle、SQL Server、H2等。 - **模块化设计**:清晰的层次结构,易于理解和扩展。 - **...
AJAX(Asynchronous JavaScript and XML)验证框架是用于在客户端进行数据验证的工具,它可以提高用户体验,因为在提交数据到服务器之前就能发现并处理错误。以下是一些流行的AJAX验证框架的详细说明: 1. ASP.NET ...
- **Bootstrap**:流行的前端框架,提供丰富的UI组件。 - **NBL.js**:轻量级的前端构建工具。 - **Build Tools**:构建工具帮助开发者自动化完成编译、压缩等任务。 - **Concatenation**:合并多个文件为一个...
EasyUI是基于jQuery的一个强大且易用的前端框架,它提供了丰富的组件和功能,如表格、对话框、菜单、布局等,极大地简化了网页的构建过程。然而,如同所有软件工具一样,EasyUI在实际应用中也可能出现错误或不兼容性...