Posted in Javascript onOctober 24, 2010
因为是辅助类库,所以为了兼容所有其他框架和类库,采用了包装器的方式对对象进行扩展。D类库的最主要的内容是针对js常用内置对象的扩展,比如:String,Number,Array,Date等,这些扩展偏于具体的业务逻辑,比如对String扩展的trim方法、对Date扩展的toStr方法等,都是对一些常用但对象本身不支持且框架类库也不支持或不完整支持的功能扩展。同时通过对应包装器的包装我们可以通过链式方法来操作对象,最后每个包装器都提供了拆箱(即还原为原生对象)方法。故包装器提供的实质是一个装箱、操作、拆箱的过程。
命名空间:
var D = {};
部分功能如下:
. String包装器
(function(){ //包装String D.str = function(s){ if(! (this instanceof y.str))return new y.str(s); this.val = (s!==undefined) ? s.toString() : ""; }; D.str.prototype = { //删除字符串两边空白 trim : function(type){ var types = {0:"(^\\s+)|(\\s+$)",1:"^\\s+",2:"\\s+$"}; type = type || 0; this.val = this.val.replace(new RegExp(types[type],"g"),""); return this; }, //重复字符串 repeat : function(n){ this.val = Array(n+1).join(this.val); return this; }, //字符串两边补白 padding : function(len,dire,str){ if(this.val.length>=len)return this; dire = dire || 0; //[0代表左边,1代表右边] str = str || " "; //默认为一个空白字符 var adder = []; for(var i=0,l = len - this.val.length; i<l;i++){ adder.push(str); } adder = adder.join(""); this.val = dire ? (this.val + adder) : (adder + this.val); return this; }, reverse : function(){ this.val = this.val.split("").reverse().join(""); return this; }, byteLen : function(){ return this.val.replace(/[^\x00-\xff]/g,"--").length; }, unBox : function(){ return this.val; } }; //alert(D.str(" 123 ").trim().repeat(2).padding(10,0,"x").reverse().unBox()); })();
.Array包装器
(function(){ //包装Array D.arr = function(arr){ if(!(this instanceof D.arr))return new D.arr(arr); this.val = arr || []; }; D.arr.prototype = { each : function(fn){ for(var i=0,len=this.val.length;i<len;i++){ if(fn.call(this.val[i])===false){ return this; } } return this; }, map : function(fn){ var copy = []; for(var i=0,len = this.val.length;i<len;i++){ copy.push(fn.call(this.val[i])); } this.val = copy; return this; }, filter : function(fn){ var copy = []; for(var i=0,len=this.val.length;i<len;i++){ fn.call(this.val[i]) && copy.push(this.val[i]); } this.val = copy; return this; }, remove : function(obj,fn){ fn = fn || function(m,n){ return m===n; }; for(var i=0,len = this.val.length;i<len;i++){ if(fn.call(this.val[i],obj)===true){ this.val.splice(i,1); } } return this; }, unique : function(){ var o = {},arr = []; for(var i=0,len = this.val.length;i<len;i++){ var itm = this.val[i]; (!o[itm] || (o[itm]!==itm) )&& (arr.push(itm),o[itm] = itm); } this.val = arr; return this; }, indexOf : function(obj,start){ var len = this.val.length,start = ~~start; start < 0 && (start+= len); for(;start<len;start++){ if(this.val[start]===obj)return start; } return -1; }, lastIndexOf : function(obj,start){ var len = this.val.length,start = arguments.length === 2 ? ~~start : len-1; start = start < 0 ? (start+len) : (start>=len?(len-1):start); for(;start>-1;start--){ if(this.val[start] === obj)return start; } return -1; }, unBox : function(){ return this.val; } }; //alert( D.arr(["123",123]).unique().unBox()); //alert(D.arr([1,2,3]).map(function(i){return ++i;}).filter(function(i){return i>2;}).remove(3).unBox()); })();
.Number包装器
(function(){ //包装Number D.num = function(num){ if(!(this instanceof D.num))return new D.num(num); this.val = Number(num) || 0; }; D.num.prototype = { padZore : function(len){ var val = this.val.toString(); if(val.length>=len)return this; for(var i=0,l = len-val.length;i<l;i++){ val = "0" + val; } return val; }, floatRound : function(n){ n = n || 0; var temp = Math.pow(10,n); this.val = Math.round(this.val * temp)/temp; return this; }, unBox : function(){ return this.val; } }; //alert(D.num(3.1235888).floatRound(3).unBox()); })();
.Date包装器
(function(){ //包装Date D.date = function(date){ if(!(this instanceof D.date))return new D.date(date); if(!(date instanceof Date)){ var d = new Date(date); this.val = (d == "Invalid Date" || d == "NaN") ? new Date() : new Date(date); }else{ this.val = date; } }; D.date.prototype = { toStr : function(tpl){ var date = this.val,tpl = tpl || "yyyy-MM-dd hh:mm:ss"; var v = [date.getFullYear(),date.getMilliseconds(),date.getMonth()+1,date.getDate(),date.getHours(),date.getMinutes(),date.getSeconds()]; var k = "MM,M,dd,d,hh,h,mm,m,ss,s".split(","); var kv = {"yyyy":v[0],"yy":v[0].toString().substring(2),"mmss":("000"+v[1]).slice(-4),"ms":v[1]}; for(var i=2;i<v.length;i++){ kv[k[(i-2)*2]] = ("0" + v[i]).slice(-2); kv[k[(i-2)*2+1]] = v[i]; } for(var k in kv){ tpl = tpl.replace(new RegExp( k,"g"),kv[k]); } return tpl; }, unBox : function(){ return this.val; } }; //alert(D.date("2017-123-12").toStr("yyyy-MM-dd hh:mm:ss ms-mmss")); // alert(D.date("2017").unBox()); })();
.最后为了在脱离其他框架类库的情况下D也可以承担dom操作方面的任务,实现了Dom包装器,如下:
(function(){ 2 //包装Dom 3 D.dom = function(node){ 4 if(!(this instanceof D.dom))return new D.dom(node); 5 if(typeof node === "undefined"){ 6 node = document.body; 7 }else if(typeof node == "string"){ 8 node = document.getElementById(node); 9 !node && (node = document.body); }else{ !node.getElementById && (node = document.body); } this.val = node; }; D.dom.prototype = { inner : function(value){ this.val.innerHTML ? (value = value || "",this.val.innerHTML = value) : (value = value || 0,this.val.value = value); return this; }, attr : function(k,v){ if(typeof k == "object"){ for(var m in k){ this.val[m] = k[m]; } }else{ this.val[k] = v; } return this; }, css : function(k,v){ var style = this.val.style; if(typeof k == "object"){ for(var m in k){ style[m] = k[m]; } }else{ style[k] = v; } return this; }, addClass : function(cls){ var clsName = " " + this.val.className + " "; (clsName.indexOf(" " + cls + " ")==-1) && (clsName = (clsName + cls).replace(/^\s+/,"")); this.val.className = clsName; return this; }, removeClass : function(cls){ var clsName = " " + this.val.className + " "; this.val.className = clsName.replace(new RegExp(" "+cls+ " ","g"),"").replace(/(^\s+)|(\s+$)/,""); return this; }, addEvent : function(evType,fn){ var that = this, typeEvent = this.val["on"+evType]; if(!typeEvent){ (this.val["on"+evType] = function(){ var fnQueue = arguments.callee.funcs; for(var i=0;i<fnQueue.length;i++){ fnQueue[i].call(that.val); } }).funcs =[fn]; }else{ typeEvent.funcs.push(fn); } return this; }, delEvent : function(evType,fn){ if(fn===undefined){ this.val["on"+evType] = null; }else{ var fnQueue = this.val["on"+evType].funcs; for(var i=fnQueue.length-1;i>-1;i--){ if(fnQueue[i] === fn){ fnQueue.splice(i,1); break; } } fnQueue.length==0 && (this.val["on"+evType] = null); } return this; }, unBox : function(){ return this.val; } }; //静态方法 var __ = D.dom; __.$ = function(id){ return typeof id == "string" ? document.getElementById(id) : id; }; __.$$ = function(tag,box){ return (box===undefined?document:box).getElementsByTagName(tag); }; __.$cls = function(cls,tag,node){ node = node === undefined ? document : node; cls = cls.replace(/(\.)|(^\s+)|(\s+$)/g,""); if(node.getElementsByClassName)return node.getElementsByClassName(cls); tag = tag === undefined ? "*" : tag; var filter = [], nodes = (tag==="*" && node.all) ? node.all : node.getElementsByTagName(tag); for(var i=0,j=nodes.length;i<j;i++){ nodes[i].nodeType==1 && ((" " + nodes[i].className + " ").indexOf(" "+cls+ " ")!=-1) && filter.push(nodes[i]); } return filter; }; //静态方法结束 alert(D.dom.$cls(".abc").length); })();
Dom包装器的实例对象负责当前dom节点的自身操作。而"静态方法"部分则是提供了dom选择器的基本实现。
以上就是D类库的初级版本,其中的重要部分——对内置对象的扩展目前只有较少的方法扩展,比如对Number的扩展,在基于web的财务软件中,用到相当多的数字操作,其中有一些是常用处理,就可以将其添加入Number包装器,好处也是显而易见的。
最后如果你看到了这篇文章,也有足够的想法,我希望你能尽你所能来给于包装器更多的方法扩展,你的其中的一些主意可能会成为D成熟版本的一部分。
JavaScript类库D
声明:登载此文出于传递更多信息之目的,并不意味着赞同其观点或证实其描述。
Reply on: @reply_date@
@reply_contents@