zYUI3 Node对象实现链式调用的方式如下:
Y.one('#id').setStyle('border','1px').setAttribute('title','test');
大家都知道,JavaScript链式调用只是语法的招数。依据JavaScript的灵活性,实现的方法也不止一种,一起来看。
注:前两种实现我直接拷贝了 zhouyrt的文章 JavaScript中链式调用之研习 中的代码,在此谢过。
第一种链式调用方法,代码如下。缺点是每个需要链式调用的方法都要返回当前对象。
function ClassA(){ this.prop1 = null; this.prop2 = null; this.prop3 = null; } ClassA.prototype = { method1 : function(p1){ this.prop1 = p1; return this; }, method2 : function(p2){ this.prop2 = p2; return this; }, method3 : function(p3){ this.prop3 = p3; return this; } } var obj = new ClassA(); //链式调用 obj.method1(1).method2(2).method(3); // obj -> prop1=1,prop2=2,prop3=3
第二种方法可以在不改变原有方法的情况下模拟链式调用。无论原有方法是否返回当前对象,都可以使用。
但使用的风格略有不同。如下:
function chain(obj){ var fn = function(method){ if(arguments.length <= 0){ return fn; } var args = Array.prototype.slice.call(arguments, 1); obj[method].apply(obj, args); return fn; } return fn; } function ClassB(){ this.prop1 = null; this.prop2 = null; this.prop3 = null; } ClassB.prototype = { method1 : function(p1){ this.prop1 = p1; }, method2 : function(p2){ this.prop2 = p2; }, method3 : function(p3){ this.prop3 = p3; } } //链式调用模拟方式 var result = chain(obj)('method1',4)('method2',5)('method3',6)(); // result -> prop1=4,prop2=5,prop3=6
接下来介绍YUI中Node类实现的链式调用方法。
在YUI3中,Node类的基础是Dom,很多Node类的方法都是调用Dom类的同名方法,如上面提到的setAttribute、setStyle等,
在Dom类源码中也未设置返回本对象,在Node类提供了importMethods方法来导入Dom中相同的方法并支持链式调用。示例代码如下:
//Dom类及静态方法 function Dom(id){ this.dom = document.getElementById(id); } Dom.setStyle = function(node,name,value){ node.dom.style[name] = value; } Dom.setAttribute = function(node,name,v){ node.dom.setAttribute(name,v); } //Node类 function Node(id){ this.dom = document.getElementById(id); } //添加方法的函数 Node.addMethod = function(method,fn){//,context Node.prototype[method] = function(){ var me = this; //Array.prototype.unshift.call(arguments,me); //or arguments = Array.prototype.slice.call(arguments); arguments.unshift(me); fn.apply(me,arguments); return me; } } //批量添加方法的函数 Node.importMethods = function(host,methods){ for(var i in methods){ var m = methods[i]; var fn = host[m]; Node.addMethod(m,fn); } } //定义需要给Node类添加的方法名 列表 var methods = ['setStyle','setAttribute']; //使用批量添加方法的函数将Dom中的相关方法添加到Node中 Node.importMethods(Dom,methods); //可以在Node中进行链式调用 var n = new Node('log').setStyle('border','2px solid red').setAttribute('t',22);
在实际使用中,可以对原有的对象方法(如Dom中的方法)扩展到另一个类中(如Node类),在Node类中进行链式调用。当然也可以使用同样的方式(importMethods)不扩展而是覆盖Dom中的方法。