有跟贴分享的童鞋一律有分,大家也发一发自己平时用的小东东呀。
PS:代码太长发不了,只好这样了.点击美化
(function(){utils={proxy:function(){this.string.proxy();this.date.proxy();this.cookie.proxy();this.dataType2.proxy();window.dataType=this.dataType},dataType:{get:function(a){return Object.prototype.toString.call(a).match(/^\[object\s(.*)\]$/)[1]},is:function(a,b){return b.split(',').length>1?b.toLowerCase().indexOf(this.get(a).toLowerCase())>-1:this.get(a).toLowerCase()==b.toLowerCase()}},dataType2:{get:function(){return Object.prototype.toString.call(this).match(/^\[object\s(.*)\]$/)[1]},is:function(a){return a.split(',').length>0?a.toLowerCase().indexOf(this.getType().toLowerCase())>-1:this.getType().toLowerCase()==a.toLowerCase()},proxy:function(){Object.prototype.isType=this.is;Object.prototype.getType=this.get}},string:{byteLength:function(){if(this.isEmpty()){return 0};var match=this.match(/[^\x00-\x80]/g);return(this.length+(!match?0:match.length))},cut:function(a,b,c){if(this.isEmpty()){return this}var d=this,e=0,f='',g=b?d.byteLength():d.length,h=(c?(g>a?c:''):'');if(a>=g){return this};for(i=0;i<d.length;i++){if(b){e+=(d.charCodeAt(i)>255)?2:1;f+=d.charAt(i);if(e>=a){return f+h}}else{if(i>=a){return f+h}f+=d.charAt(i)}};return d+h},trim:function(){return this.replace(/(^\s*)|(\s*$)/g,"")},isEmpty:function(){return this.trim().length==0},format:function(){var args=arguments;return this.replace(/\{(\d+)\}/g,function(m,i){return args[i]})},toFloat:function(a,b){a=dataType.is(a,'number')?a:!1,b=dataType.is(b,'boolean')?b:!0;try{var c=a?(b?(this*1).toFixed(a)*1:this.toString().replace(new RegExp("([0-9]+\.[0-9]{"+a+"})[0-9]*","g"),"$1")*1):(this*1);return isNaN(c)?this:c}catch(e){return this*1}},toDate:function(){var a=this,b={"-":!0,"年":!0,"月":!0,"日":!1,"时":!0,"分":!0,"秒":!1};if(dataType.is(a,'string')){for(var i in b){a=a.replace(i,b[i]?'/':'')};var c=new Date(Date.parse(a));if(isNaN(c)){throw new Error('源数据['+this+']无法转化为日期格式');return this};return c}else{return new Date(a)}},proxy:function(){String.prototype.format=this.format;String.prototype.toFloat=Number.prototype.toFloat=this.toFloat;String.prototype.toDate=Number.prototype.toDate=this.toDate;String.prototype.byteLength=this.byteLength;String.prototype.cut=this.cut;String.prototype.trim=this.trim;String.prototype.isEmpty=this.isEmpty}},date:{format:function(b){var a=this,o={"M+":a.getMonth()+1,"d+":a.getDate(),"h+":a.getHours(),"m+":a.getMinutes(),"s+":a.getSeconds(),"W":["日","一","二","三","四","五","六"][a.getDay()],"q+":Math.floor((a.getMonth()+3)/3),"S":a.getMilliseconds()};if(/(y+)/.test(b)){b=b.replace(RegExp.$1,(a.getFullYear()+"").substr(4-RegExp.$1.length))};for(var k in o){if(new RegExp("("+k+")").test(b)){b=b.replace(RegExp.$1,RegExp.$1.length==1?o[k]:("00"+o[k]).substr((""+o[k]).length))}};return b},add:function(a){if(a.length==0){return this}var b=this,c=a.match(/((-\d+)+|(\d+))/g),d=a.match(/y+|M+|d+|h+|m+|s+/g),e={'y':function(f){return b.setFullYear(b.getFullYear()+f*1)},'M':function(f){return b.setMonth(b.getMonth()+f*1)},'d':function(f){return b.setDate(b.getDate()+f*1)},'h':function(f){return b.setHours(b.getHours()+f*1)},'m':function(f){return b.setMinutes(b.getMinutes()+f*1)},'s':function(f){return b.setSeconds(b.getSeconds()+f*1)}};for(var i=0;i<c.length;i++){e[d[i].substr(0,1)](c[i]).toDate()};return b},proxy:function(){Date.prototype.format=this.format;Date.prototype.add=this.add}},cookie:{set:function(a){if(dataType.is(a,'string,number')){a={value:a}}else if(!a){return};var time=a.time?'; expis='+new Date().add(a.time).toGMTString():'',path=a.path?'; path='+a.path:'',domain=a.domain?'; domain='+a.domain:'',secure=a.secure?'; secure':'',value=a.value?encodeURIComponent(a.value):'';document.cookie=[this,'=',value,time,path,domain,secure].join('')},get:function(){if(!document.cookie||(document.cookie&&document.cookie=='')){return''};var a=document.cookie.split(";");for(var i=0;i<a.length;i++){var arr=a[i].split("=");if(arr[0].trim()==this.trim()){var b=decodeURIComponent(arr[1]);return b=='undefined'?'':b}};return''},del:function(){if(this.isEmpty()){this.delAllCookie()}else{this.setCookie({time:'-1s'})}},delAll:function(){var keys=document.cookie.match(/[^ =;]+(?=\=)/g);if(keys){for(var i=0;i<keys.length;i++){keys[i].setCookie({time:'-1s'})}}},proxy:function(){String.prototype.getCookie=this.get;String.prototype.setCookie=this.set;String.prototype.delCookie=this.del;String.prototype.delAllCookie=this.delAll}}};utils.proxy()})();
PS:代码太长发不了,只好这样了.点击美化
(function(){utils={proxy:function(){this.string.proxy();this.date.proxy();this.cookie.proxy();this.dataType2.proxy();window.dataType=this.dataType},dataType:{get:function(a){return Object.prototype.toString.call(a).match(/^\[object\s(.*)\]$/)[1]},is:function(a,b){return b.split(',').length>1?b.toLowerCase().indexOf(this.get(a).toLowerCase())>-1:this.get(a).toLowerCase()==b.toLowerCase()}},dataType2:{get:function(){return Object.prototype.toString.call(this).match(/^\[object\s(.*)\]$/)[1]},is:function(a){return a.split(',').length>0?a.toLowerCase().indexOf(this.getType().toLowerCase())>-1:this.getType().toLowerCase()==a.toLowerCase()},proxy:function(){Object.prototype.isType=this.is;Object.prototype.getType=this.get}},string:{byteLength:function(){if(this.isEmpty()){return 0};var match=this.match(/[^\x00-\x80]/g);return(this.length+(!match?0:match.length))},cut:function(a,b,c){if(this.isEmpty()){return this}var d=this,e=0,f='',g=b?d.byteLength():d.length,h=(c?(g>a?c:''):'');if(a>=g){return this};for(i=0;i<d.length;i++){if(b){e+=(d.charCodeAt(i)>255)?2:1;f+=d.charAt(i);if(e>=a){return f+h}}else{if(i>=a){return f+h}f+=d.charAt(i)}};return d+h},trim:function(){return this.replace(/(^\s*)|(\s*$)/g,"")},isEmpty:function(){return this.trim().length==0},format:function(){var args=arguments;return this.replace(/\{(\d+)\}/g,function(m,i){return args[i]})},toFloat:function(a,b){a=dataType.is(a,'number')?a:!1,b=dataType.is(b,'boolean')?b:!0;try{var c=a?(b?(this*1).toFixed(a)*1:this.toString().replace(new RegExp("([0-9]+\.[0-9]{"+a+"})[0-9]*","g"),"$1")*1):(this*1);return isNaN(c)?this:c}catch(e){return this*1}},toDate:function(){var a=this,b={"-":!0,"年":!0,"月":!0,"日":!1,"时":!0,"分":!0,"秒":!1};if(dataType.is(a,'string')){for(var i in b){a=a.replace(i,b[i]?'/':'')};var c=new Date(Date.parse(a));if(isNaN(c)){throw new Error('源数据['+this+']无法转化为日期格式');return this};return c}else{return new Date(a)}},proxy:function(){String.prototype.format=this.format;String.prototype.toFloat=Number.prototype.toFloat=this.toFloat;String.prototype.toDate=Number.prototype.toDate=this.toDate;String.prototype.byteLength=this.byteLength;String.prototype.cut=this.cut;String.prototype.trim=this.trim;String.prototype.isEmpty=this.isEmpty}},date:{format:function(b){var a=this,o={"M+":a.getMonth()+1,"d+":a.getDate(),"h+":a.getHours(),"m+":a.getMinutes(),"s+":a.getSeconds(),"W":["日","一","二","三","四","五","六"][a.getDay()],"q+":Math.floor((a.getMonth()+3)/3),"S":a.getMilliseconds()};if(/(y+)/.test(b)){b=b.replace(RegExp.$1,(a.getFullYear()+"").substr(4-RegExp.$1.length))};for(var k in o){if(new RegExp("("+k+")").test(b)){b=b.replace(RegExp.$1,RegExp.$1.length==1?o[k]:("00"+o[k]).substr((""+o[k]).length))}};return b},add:function(a){if(a.length==0){return this}var b=this,c=a.match(/((-\d+)+|(\d+))/g),d=a.match(/y+|M+|d+|h+|m+|s+/g),e={'y':function(f){return b.setFullYear(b.getFullYear()+f*1)},'M':function(f){return b.setMonth(b.getMonth()+f*1)},'d':function(f){return b.setDate(b.getDate()+f*1)},'h':function(f){return b.setHours(b.getHours()+f*1)},'m':function(f){return b.setMinutes(b.getMinutes()+f*1)},'s':function(f){return b.setSeconds(b.getSeconds()+f*1)}};for(var i=0;i<c.length;i++){e[d[i].substr(0,1)](c[i]).toDate()};return b},proxy:function(){Date.prototype.format=this.format;Date.prototype.add=this.add}},cookie:{set:function(a){if(dataType.is(a,'string,number')){a={value:a}}else if(!a){return};var time=a.time?'; expis='+new Date().add(a.time).toGMTString():'',path=a.path?'; path='+a.path:'',domain=a.domain?'; domain='+a.domain:'',secure=a.secure?'; secure':'',value=a.value?encodeURIComponent(a.value):'';document.cookie=[this,'=',value,time,path,domain,secure].join('')},get:function(){if(!document.cookie||(document.cookie&&document.cookie=='')){return''};var a=document.cookie.split(";");for(var i=0;i<a.length;i++){var arr=a[i].split("=");if(arr[0].trim()==this.trim()){var b=decodeURIComponent(arr[1]);return b=='undefined'?'':b}};return''},del:function(){if(this.isEmpty()){this.delAllCookie()}else{this.setCookie({time:'-1s'})}},delAll:function(){var keys=document.cookie.match(/[^ =;]+(?=\=)/g);if(keys){for(var i=0;i<keys.length;i++){keys[i].setCookie({time:'-1s'})}}},proxy:function(){String.prototype.getCookie=this.get;String.prototype.setCookie=this.set;String.prototype.delCookie=this.del;String.prototype.delAllCookie=this.delAll}}};utils.proxy()})();
/// <summary>
/// String,Number原型扩展:保留指定的小数位数[可选择是否使用四舍五入]
/// </summary>
/// <param name="a">需要保留的小数位</param>
/// <param name="b">是否是舍五入[可选项:默认true]</param>
/// <returns>数据类型:Number(浮点数)</returns>
四舍五入: (2.35555).toFloat(3)=2.356
非四舍五入: (2.35555).toFloat(3,!1)=2.355
简单容错: (2.35555).toFloat(!0)=2.35555四舍五入: "2.35555".toFloat(3)=2.356
非四舍五入: "2.35555".toFloat(3,!1)=2.355
简单容错: "2.35555".toFloat(!0)=2.35555/// <summary>
/// String原型扩展:去除左右空格
/// </summary>
/// <returns>数据类型:String</returns>
调用方式:'aaaa中 '.trim()='aaaa中'/// <summary>
/// String原型扩展:按字节取长度,汉字计为两字节
/// </summary>
/// <returns>字符串总长度</returns>
调用方式:'aaaa中'.byteLength()=6/// <summary>
/// String原型扩展:字符串等效项替换[string.Format()伪实现]
/// </summary>
/// <param name="arguments">arguments数组</param>
/// <returns>替换后的字符串</returns>
调用方式:"a{0}b{1}c{2}".format("x","y","z")="axbycz"/// <summary>
/// String原型扩展:是否空字符串
/// </summary>
/// <returns>Boolean</returns>
调用方式:"".isEmpty()=true
调用方式:"a".isEmpty()=false/// <summary>
/// String原型扩展:截取指定长度的字符串
/// </summary>
/// <param name="a">要截取的长度</param>
/// <param name="b">是否将汉字计为2个长度:true|false</param>
/// <param name="c">截取的长度小于原字符串的总长度时,附加的文本,比如:...</param>
/// <returns>截取后的字符串</returns>
调用方式:"1中中2345".cut(3)="1中中"
调用方式:"1中中2345".cut(3,true)="1中"
调用方式:"1中中2345".cut(3,false)="1中中"
调用方式:"1中中2345".cut(3,true,"...")="1中..."
调用方式:"1中中2345".cut(3,false,"...")="1中中..."
调用方式:"1中中2345".cut(9,true,"...")="1中中2345"
调用方式:"1中中2345".cut(7,false,"...")="1中中2345"/// <summary>
/// String,Number原型扩展:转换为日期格式[函数中定义了一个常规的替换项模板,有特殊使用时可进行修改]
/// </summary>
/// <returns>数据类型:Date</returns>
调用方式:1:Number:(1000*60*60*24).toDate()=Fri Jan 2 08:00:00 UTC+0800 1970
调用方式:2:String:"2012年10月27日 11:56:12".toDate()=Sat Oct 27 11:56:12 UTC+0800 2012/// <summary>
/// Date原型扩展:日期运算
/// 参数格式:yMdhms分别表示[年月日时分秒,前面使用正负数字表示做加运算还是减运算]1y=加1年,1M=加1个月,1d=加1天,1h=加1个小时,1m=加1分钟,1s=加1秒钟
/// </summary>
/// <param name="a">加减日期{参数格式:参考上面的说明}</param>
/// <returns>数据类型:Date</returns>
调用方式:new Date().add('1y1M1d1h1m1s')=Sat Nov 30 00:07:16 UTC+0800 2013/// <summary>
/// Date原型扩展:日期格式化
/// </summary>
/// <param name="a">格式化模板[yMdhms:分别表示-年月日时分秒,q="季度",W="星期"]</param>
/// <returns>数据类型:String</returns>
调用方式:new Date().format('yyyy-MM-dd 第q季度 星期W hh:mm:ss')=2012-10-28 第4季度 星期日 23:06:15/// <summary>
/// 复合使用示例
/// </summary>
调用方式:1:Number:(1000*60*60*24).toDate().add('1y1M1d1h1m1s').format('yyyy-MM-dd 第q季度 星期W hh:mm:ss')=1971-02-03 第1季度 星期三 09:01:01
调用方式:2:String:"2012年10月27日 11:56:12".toDate().add("1y1M1d1h1m1s").format("yyyy-MM-dd 第q季度 星期W hh:mm:ss")=2013-11-28 第4季度 星期四 12:57:13/// <summary>
/// String原型扩展:设置cookie
/// </summary>
/// <param name="a">完整格式:{value:值,time:有效日期[与日期运算中的参数格式一致],path:访问目录,domain:域,secure:安全性}</param>
/// <returns>以调用对象作为cookie的键名设置cookie</returns>
最简调用:"test".setCookie(1||"1");//设置cookie:test=1,有效日期:关闭浏览器后立刻失效
字面量传参:"test".setCookie({value:2,time:"1y"});//设置cookie:test=2,有效日期:1年/// <summary>
/// String原型扩展:获取cookie
/// </summary>
/// <returns>以调用对象作为cookie的键名获取它的cookie值,不存在时返回空字符串</returns>
调用方式:"test".getCookie();//获取名称为test的cookie值/// <summary>
/// String原型扩展:删除cookie
/// </summary>
/// <returns>以调用对象作为cookie的键名删除它的cookie,当调用对象是空字符串时可清除所有cookie</returns>
调用方式:"test".delCookie();//删除键名为test的cookie
调用方式:"".delCookie();//删除所有cookie
Date.prototype.format = function(format)
{
var o ={
"M+" : this.getMonth()+1, //month
"d+" : this.getDate(), //day
"h+" : this.getHours(), //hour
"s+" : this.getSeconds(), //second
"m+" : this.getMinutes(), //minute
"q+" : Math.floor((this.getMonth()+3)/3), //quarter
"S" : this.getMilliseconds() //millisecond
}
if(/(y+)/.test(format))
format=format.replace(RegExp.$1,(this.getFullYear()+"").substr(4 - RegExp.$1.length));
for(var k in o)
if(new RegExp("("+ k +")").test(format))
format = format.replace(RegExp.$1,RegExp.$1.length==1 ? o[k] : ("00"+ o[k]).substr((""+ o[k]).length));
return format;
};
String.prototype.Trim=function(){
return this.replace(/(^\s*)|(\s*$)/g,'');
};
Array.prototype.contain=function(value){
if(this!=null && this.length>0){
for(var i=0;i<this.length;i++)
{
if(this[i]==value){
return true;
}
}
}
return false;
};
Array.prototype.indexOf = function(val) {
for (var i = 0; i < this.length; i++) {
if (this[i] == val) return i;
}
return -1;
};
Array.prototype.remove = function(val) {
var index = this.indexOf(val);
if (index > -1) {
this.splice(index, 1);
}
};//获取上一个节点
function getPreviousChild(obj) {
var result = obj.previousSibling;
while (!result.tagName) {
result = result.previousSibling;
}
return result;
}
//获取下一个节点
function getNextChild(obj) {
var result = obj.nextSibling;
while (!result.tagName) {
result = result.nextSibling;
}
return result;
} /********************
* 取窗口滚动条滚动高度
******************/
function getScrollTop()
{
return window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop ;
};
/********************
* 取窗口可视范围的高度
*******************/
function getClientHeight()
{
return (navigator.userAgent.toLowerCase().indexOf('opera') != -1)?document.body.clientHeight:document.documentElement.clientHeight;
};
/********************
* 取窗口可视范围的宽度
*******************/
function getClientWidth()
{
return (navigator.userAgent.toLowerCase().indexOf('opera') != -1)?document.body.clientWidth:document.documentElement.clientWidth;
};
// 动态导入js
function include(src,encoding,fun)
{
var s = $C('script');
s.type='text/javascript';
s.charset=encoding; //'gb2312';
s.src = src;
var tags =$$('head');
if(typeof(fun)=='function'){
if( document.all ){
s.onreadystatechange = function(){
if(/(complete|loaded)/.test(this.readyState)){
fun(); s.onreadystatechange = null; s.parentNode.removeChild(s);
}};
}else{
s.onload = function(){ fun(); s.onload = null; s.parentNode.removeChild(s); };
}
}
tags[0].appendChild(s);
};
// 绑定事件
function bindEvent(obj,evt,fun)
{
if(window.addEventListener){
obj.addEventListener(evt, function(e){ fun(e);},false);
}else{
obj.attachEvent('on'+evt,fun);
}
} function getAbsPoint(e)
{
var x = e.offsetLeft;
var y = e.offsetTop;
while(e = e.offsetParent)
{
x += e.offsetLeft;
y += e.offsetTop;
}
return {'x': x, 'y': y};
};
正在导入自己的。
Array.prototype.contain与Array.prototype.indexOf功能性重复
这一点,与“除非是为了和新的 JavaScript 引擎兼容”的原则所产生的效果正好相反。如果按照那个原则,只在低版本引擎中扩展原型,那么就可以无需连同复制定义扩展的JS,直接把使用代码复制到高版本引擎中使用即可,因为高版本正好支持了那些功能。否则就不行了。3.一旦不禁止使用这种方法,那么各种对原型的扩展就会存在,到时可能除了你的扩展,还同时有别人的JS库里含有对同样方法的扩展,而实现的目标可能有差异,这样无论是你重载了他,还是他重载了你,都会很混乱。合并多个对原型有相同覆盖部分的扩展时,也会比较麻烦,更不用说在取舍时是否还要比较实现方法的好坏。而如果使用类库形式,则只要想调用哪个库的哪个方法就调用哪个,不需要的不调用即可。4.扩展原型必然会改变原型结构。在其它地方如果涉及到对原型结构进行遍历操作,或者是针对原来的结构与方法进行的特定操作时,可能与其针对原结构而设计的预期冲突而造成该部分的功能异常或者出错。比如我曾举例过的改变ARRAY的LENGTH后,所有新声明的数组都不能再通过LENGTH进行FOR遍历,虽然这是比较极端和不普遍的修改,但其它修改也会造成类似现象,隐患始终存在,只看诱因是否出现,而你不能保证别人一定不会使用与之可能冲突的代码,甚至你也想不到所有也许会冲突的可能性。所有BUG都是因为在我们意料之外的使用情况,意料之内的我们自然已经解决了。概括的话,扩展原型和建立类库是效果截然相反的两种代码组织方法。扩展原型不利于代码的组织、使用、管理,甚至是理解,而且容易与其它没有考虑到你这些扩展或重载的代码产生差异性错误或不同结果,又或者是因为相同的重载而产生覆盖冲突。实际所衍生的问题就多了。
就像是我如果要对Object原型进行扩展时一样。jQuery这么成熟的框架,居然也没有在for in中使用hasOwnProperty()来过滤原型扩展。看来不是人家粗心,是这种方式确实在应用中应该被避免为佳要是我自己用的话倒是没什么问题,这么提供出来确实是有点欠考虑了。之所以使用原型扩展的方式,我只是想使得调用更直接,其实在上传这些代码之前,所有的代码都是兼容类库方式调用和基于对象原型方式调用的。只是因为参数的处理部份多了些,所以被我全部去除了。只保留了基于对象原型方式调用
改成类库方式也简单就是。加多个参数替换this倒也方便
想先考虑一下调用方式的问题。
Object的原型扩展这个是直接放弃了
数组呢也很重要,对其直接进行原型扩展也是很容易出现错误的,虽然我本人不用for in遍历,但架不住别人已经用过的。所以我发出的代码里并没有对数组的原型扩展,就是基于这个原因被我先抠掉了Date我觉得还是直接使用原型扩展就可以了
String嘛,有打算保留目前这种原型扩展的方式,但也有想过使用静态方法调用:String.trim(字符串)
Array嘛,这个是打算使用静态方法调用了:Array.each(arr,fn)给点意见参考下吧
不如直接写自己的 工具类 更实用至少我用的时候 知道是怎么回事
而且代码的兼容性更好Array.each ==> utils.each
先谢谢提供建议
使用Array.each这种静态方法调用,包括这些原型的扩展,其实都是出于一个相同的目的。调用简便你也应该看得出来,在写的时候,我是将对应的方法归到其所属的数据类型下面的如果这样使用:utils.each(arr,fn),
那我感觉还不如:utils.array.each(arr,fn),虽然长了点,但对方法的归属却更清晰
其他的还好说。只是在数组上可供使用的方法太多。添加,复制,合并,排重,交集,索引,过滤等等,加起来二十来种都怕是有了。所以才会使用这种伪命名空间的方式将每个方法归到对应的数据类型下面。阅读起来也更方便
主要是我写的时候就是这么一个一个写下来的。感觉结构更清晰点
'use strict';var StrUtil = (function(){var Cache = {};var FmtHelper = {
/**
* 执行用户自定义函数.
* @param {String}param 函数名称
* @param {String}propName 属性名称
* @param {String}propVal 属性值
* @param {JSON}context
* @return {String}
*@example
* var params = {
* name : 'zhang-san',
* gender : 'male'
* }
*
* var temp = (
* "hello #{name} #{gender, $exec(getTitle)}!"
* );
*
* var output = StrUtil.simpleFormat(temp, params, {
* getTitle : function(key, val, context){
* console.log(context);
* return val == 'male' ? '先生' : '小姐';
* }
* });
*
* console.log(output);
*/
exec : function(param, propName, propVal, context){
var ret = null, handler;
param = param.replace(/^\s+/g,'').replace(/\s+$/g, '');
handler = context.handlers && context.handlers[param];
if(handler instanceof Function){
ret = handler(propName, propVal, context);
}
return ret;
},
map : function(mapData, propName, propVal, context){
var handleStr = function(str){
if(!str) { return "" }
var firstChar = str.charAt(0);
if(firstChar == "'" || firstChar == "\""){
return str.substring(1, str.length - 1);
}
return str;
}
var map = (function(){
if( Cache[mapData] ){
return Cache[mapData];
} var reg = /([^,'":\s]+|'.*?'|".*?")\s*:\s*([^,'":\s]+|'.*?'|".*?")/g;
var m, k, v, newMap = {};
while(m = reg.exec(mapData)){
k = handleStr(m[1]);
v = handleStr(m[2]);
if(k && v){
newMap[k] = v;
}
}
Cache[mapData] = newMap;
return newMap;
})();
return map[propVal] || map['else'] || '';
},
/**
* 当参数超过指定长度时截取并显示省略号。
* 可按长度和宽度进行截取。
* @param {String}param 参数设置字符串
* @param {String}propVal 属性值
* @return {String}
* @example
*
* var t1 = "Hello #{0->$sub(5,l)}!"; //默认按长度截取,l可省略
* var t2 = "Hello #{0->$sub(5,w)}!";
* var t3 = "Hello #{0->$sub(5,w,>>>)}!"
*
* 1.按长度截取
* StrUtil.simpleFormat(t1, "ABCDEFG"); //Hello AB...!
* StrUtil.simpleFormat(t1, "星期六的黄昏"); //Hello 星期...!
*
* 2.按宽度截取
* StrUtil.simpleFormat(t2, "ABCDEFGHIJKLM"); //Hello ABCDEF...!
* StrUtil.simpleFormat(t2, "星期六的黄昏"); //Hello 星期六...!
*
* 3.定义省略号
* StrUtil.simpleFormat(t3, "ABCDEFGHIJKLM"); //Hello ABCDEF>>>!
* StrUtil.simpleFormat(t3, "星期六的黄昏"); //Hello 星期六>>>!
*/
sub : function(param, propName, propVal, context){
var args = param.replace(/\s+/g, '').split(',');
var max = parseInt(args[0]);
var mask = args[2] || "...";
var byWidth = args.length > 1 && args[1] == "w";
var maskLen, propLen;
if(byWidth){
maskLen = StrUtil.getStrWidth(mask);
propLen = StrUtil.getStrWidth(propVal);
}else{
maskLen = mask.length;
propLen = propVal.length;
}
if(propLen <= max){
return propVal;
} if(maskLen >= max){
return mask;
}
return (
byWidth
? StrUtil.cutStrByWidth(propVal, max - maskLen) + mask
: propVal.substring(0, max - maskLen) + mask
);
}
}var StrUtil = {
/**
* 获取字符串宽度(英文为一个宽度,中文两个).
* @param {String}str
* @return {int}
* @public
*/
getStrWidth : function(str){
if(!str){ return 0; }
var i, c, ret = 0, len = str.length;
for(i=0; i<len; i++){
c = str.charCodeAt(i);
ret += (c > 256 ? 2 : 1);
}
return ret;
}, /**
* 根据其实位置和宽度截取字符串.
* @param {String}str
* @param {int}width
* @param {int}[start] 截取开始位置, 默认为0
*/
cutStrByWidth : function(str, width, start){
if(!str || width <= 0) { return ''; }
var i, len, code, end, size = 0, ret = [];
start = start == undefined ? 0
: start < 0 ? str.length + start
: start;
end = start + width;
for(i=0, len=str.length; i<len; i++){
code = str.charCodeAt(i);
size += (code > 256 ? 2 : 1);
if(size >= start && size <= end){
ret.push(str.charAt(i));
if(size == end){ break; }
}
}
return ret.join('');
}, /**
* 根据膜拜进行简单格式化.
* @param {String}temp
* @param {JSON|Object|...}args
* @param {JSON<String, Function>}[handlers]
* @return {String}
* @public
* @example
* var t = "welcom #{0} #{1->map(f:小姐, else:先生)}";
* var t1 = "welcom #{name} #{gender->map(f:小姐, else:先生)}";
* var t2 = "全文 : #{message}\n"
* + "概要 : #{message->sub(12,w,...)}";
*
* alert(StrUtil.simpleFormat(t, "王建波", 29));
* alert(StrUtil.simpleFormat(t1, {name : "王建波", age: 29 }));
* alert(StrUtil.simpleFormat(t2, {message: "123456789ABCDEFG"}));
*/
simpleFormat : function(temp, args, handlers){
var argc = arguments.length;
if ( arguments.length == 1 ) { return temp }
if ( arguments.length > 3 || typeof arguments[1] != "object" ) {
args = [].slice.call(arguments, 1, argc);
handlers = arguments[argc -1];
}
var reg = new RegExp((
"\\\\#\\{|#\\{" //匹配变量转义符\#{或变量开始#{
+ "(\\w+)" //属性名称
+ "(?:->\\s*" //属性后可选的内置方法调用比如:#{name->sub(5)}
+ "(\\w+)\\s*\\(" //内置方法名称
+ "(" //内置方法参数
+ "(?:[^)}\"'\\n]*?|\".*?\"|'.*?')*"
+ ")"
+ "\\)"
+ ")?"
+ "\\}"
), "gi");
var valCache = {};
var context = {
handlers : handlers,
valCache : valCache
};
var replaceHandler = function(m, prop, fn, fnParam){
var propVal, fnRet, ret;
//对于转义符,直接返回"\"之后内容
if( m == "\\#{" ) { return "#{" }
//若已经计算过直接返回
if(valCache.hasOwnProperty(m)){
return valCache[m];
}
if(prop) {
propVal = args[prop] != undefined
? String(args[prop])
: "";
//若需要对返回值进行函数调用,返回函数调用结果
if(fn && FmtHelper.hasOwnProperty(fn)){
try{
fnRet = FmtHelper[fn](
fnParam,
prop,
propVal,
context
);
}catch(e){}
} ret = (fnRet == undefined || fnRet == null) ? propVal : fnRet;
}else{
ret = m;
}
valCache[m] = ret;
return ret;
};
return temp.replace(reg, replaceHandler);
}
}return StrUtil;
})();
window.onload = function(){
alert(StrUtil.simpleFormat(
"hello #{0}, #{1}!",
"张三",
"先生"
));
alert(StrUtil.simpleFormat(
"hello #{name}, #{title}!",
{name : "张三", title : "先生"}
));
var params = {
id : 'user-1',
name : '张三',
gender : 'male',
pic : 'http://www.baidu.com/img/baidu_sylogo1.gif',
details: (
"主要是我还从没有系统的学过js,理论方面自<br/>"
+ "己对很多东西的理解很浅显。因为不想说提供<br/>"
+ "了些东东出来结果造成使用者的意料之外的错<br/>"
+ "误或降低性能和效率。也包括使用时的体验等等"
)
} var temp = (
"hello #{name} #{gender->map(female:小姐, else:先生)}<hr/>"
+ "<pre>"
+ " id : #{id}<br/>"
+ " name : #{name}<br/>"
+ " gender : #{gender->map(female:女, else:男)}<br/>"
+ " pic : <img src='#{pic}' align='top'/><br/>"
+ " summary: #{details->sub(20, l, >>>)}<br/>"
+ " details: #{details}"
+ "</pre>"
); var output = StrUtil.simpleFormat(temp, params, {
getWelcome : function(key, val){
return "hello " + val + ' current time is :' + new Date();
}
}); document.getElementById('div1').innerHTML = output;
};
'use strict';var StrUtil = (function(){var Cache = {};var FmtHelper = {
/**
* 执行用户自定义函数.
* @param {String}param 函数名称
* @param {String}propName 属性名称
* @param {String}propVal 属性值
* @param {JSON}context
* @return {String}
*@example
* var params = {
* name : 'zhang-san',
* gender : 'male'
* }
*
* var temp = (
* "hello #{name} #{gender->exec(getTitle)}!"
* );
*
* var output = StrUtil.simpleFormat(temp, params, {
* getTitle : function(key, val, context){
* console.log(context);
* return val == 'male' ? '先生' : '小姐';
* }
* });
*
* console.log(output);
*/
exec : function(param, propName, propVal, context){
var ret = null, handler;
param = param.replace(/^\s+/g,'').replace(/\s+$/g, '');
handler = context.handlers && context.handlers[param];
if(handler instanceof Function){
ret = handler(propName, propVal, context);
}
return ret;
},
map : function(mapData, propName, propVal, context){
var handleStr = function(str){
if(!str) { return "" }
var firstChar = str.charAt(0);
if(firstChar == "'" || firstChar == "\""){
return str.substring(1, str.length - 1);
}
return str;
}
var map = (function(){
if( Cache[mapData] ){
return Cache[mapData];
} var reg = /([^,'":\s]+|'.*?'|".*?")\s*:\s*([^,'":\s]+|'.*?'|".*?")/g;
var m, k, v, newMap = {};
while(m = reg.exec(mapData)){
k = handleStr(m[1]);
v = handleStr(m[2]);
if(k && v){
newMap[k] = v;
}
}
Cache[mapData] = newMap;
return newMap;
})();
return map[propVal] || map['else'] || '';
},
/**
* 当参数超过指定长度时截取并显示省略号。
* 可按长度和宽度进行截取。
* @param {String}param 参数设置字符串
* @param {String}propVal 属性值
* @return {String}
* @example
*
* var t1 = "Hello #{0->sub(5,l)}!"; //默认按长度截取,l可省略
* var t2 = "Hello #{0->sub(5,w)}!";
* var t3 = "Hello #{0->sub(5,w,>>>)}!"
*
* 1.按长度截取
* StrUtil.simpleFormat(t1, "ABCDEFG"); //Hello AB...!
* StrUtil.simpleFormat(t1, "星期六的黄昏"); //Hello 星期...!
*
* 2.按宽度截取
* StrUtil.simpleFormat(t2, "ABCDEFGHIJKLM"); //Hello ABCDEF...!
* StrUtil.simpleFormat(t2, "星期六的黄昏"); //Hello 星期六...!
*
* 3.定义省略号
* StrUtil.simpleFormat(t3, "ABCDEFGHIJKLM"); //Hello ABCDEF>>>!
* StrUtil.simpleFormat(t3, "星期六的黄昏"); //Hello 星期六>>>!
*/
sub : function(param, propName, propVal, context){
var args = param.replace(/\s+/g, '').split(',');
var max = parseInt(args[0]);
var mask = args[2] || "...";
var byWidth = args.length > 1 && args[1] == "w";
var maskLen, propLen;
if(byWidth){
maskLen = StrUtil.getStrWidth(mask);
propLen = StrUtil.getStrWidth(propVal);
}else{
maskLen = mask.length;
propLen = propVal.length;
}
if(propLen <= max){
return propVal;
} if(maskLen >= max){
return mask;
}
return (
byWidth
? StrUtil.cutStrByWidth(propVal, max - maskLen) + mask
: propVal.substring(0, max - maskLen) + mask
);
}
}var StrUtil = {
/**
* 获取字符串宽度(英文为一个宽度,中文两个).
* @param {String}str
* @return {int}
* @public
*/
getStrWidth : function(str){
if(!str){ return 0; }
var i, c, ret = 0, len = str.length;
for(i=0; i<len; i++){
c = str.charCodeAt(i);
ret += (c > 256 ? 2 : 1);
}
return ret;
}, /**
* 根据其实位置和宽度截取字符串.
* @param {String}str
* @param {int}width
* @param {int}[start] 截取开始位置, 默认为0
*/
cutStrByWidth : function(str, width, start){
if(!str || width <= 0) { return ''; }
var i, len, code, end, size = 0, ret = [];
start = start == undefined ? 0
: start < 0 ? str.length + start
: start;
end = start + width;
for(i=0, len=str.length; i<len; i++){
code = str.charCodeAt(i);
size += (code > 256 ? 2 : 1);
if(size >= start && size <= end){
ret.push(str.charAt(i));
if(size == end){ break; }
}
}
return ret.join('');
}, /**
* 根据膜拜进行简单格式化.
* @param {String}temp
* @param {JSON|Object|...}args
* @param {JSON<String, Function>}[handlers]
* @return {String}
* @public
* @example
* var t = "welcom #{0} #{1->map(f:小姐, else:先生)}";
* var t1 = "welcom #{name} #{gender->map(f:小姐, else:先生)}";
* var t2 = "全文 : #{message}\n"
* + "概要 : #{message->sub(12,w,...)}";
*
* alert(StrUtil.simpleFormat(t, "王建波", 29));
* alert(StrUtil.simpleFormat(t1, {name : "王建波", age: 29 }));
* alert(StrUtil.simpleFormat(t2, {message: "123456789ABCDEFG"}));
*/
simpleFormat : function(temp, args, handlers){
var argc = arguments.length;
if ( arguments.length == 1 ) { return temp }
if ( arguments.length > 3 || typeof arguments[1] != "object" ) {
args = [].slice.call(arguments, 1, argc);
handlers = arguments[argc -1];
}
var reg = new RegExp((
"\\\\#\\{|#\\{" //匹配变量转义符\#{或变量开始#{
+ "(\\w+)" //属性名称
+ "(?:->\\s*" //属性后可选的内置方法调用比如:#{name->sub(5)}
+ "(\\w+)\\s*\\(" //内置方法名称
+ "(" //内置方法参数
+ "(?:[^)}\"'\\n]*?|\".*?\"|'.*?')*"
+ ")"
+ "\\)"
+ ")?"
+ "\\}"
), "gi");
var valCache = {};
var context = {
handlers : handlers,
valCache : valCache
};
var replaceHandler = function(m, prop, fn, fnParam){
var propVal, fnRet, ret;
//对于转义符,直接返回"\"之后内容
if( m == "\\#{" ) { return "#{" }
//若已经计算过直接返回
if(valCache.hasOwnProperty(m)){
return valCache[m];
}
if(prop) {
propVal = args[prop] != undefined
? String(args[prop])
: "";
//若需要对返回值进行函数调用,返回函数调用结果
if(fn && FmtHelper.hasOwnProperty(fn)){
try{
fnRet = FmtHelper[fn](
fnParam,
prop,
propVal,
context
);
}catch(e){}
} ret = (fnRet == undefined || fnRet == null) ? propVal : fnRet;
}else{
ret = m;
}
valCache[m] = ret;
return ret;
};
return temp.replace(reg, replaceHandler);
}
}return StrUtil;
})();window.onload = function(){
alert(StrUtil.simpleFormat(
"hello #{0}, #{1}!",
"张三",
"先生"
));
alert(StrUtil.simpleFormat(
"hello #{name}, #{title}!",
{name : "张三", title : "先生"}
));
var params = {
id : 'user-1',
name : '张三',
gender : 'male',
pic : 'http://www.baidu.com/img/baidu_sylogo1.gif',
details: (
"主要是我还从没有系统的学过js,理论方面自<br/>"
+ "己对很多东西的理解很浅显。因为不想说提供<br/>"
+ "了些东东出来结果造成使用者的意料之外的错<br/>"
+ "误或降低性能和效率。也包括使用时的体验等等"
)
} var temp = (
"hello #{name} #{gender->map(female:小姐, else:先生)}<hr/>"
+ "<pre>"
+ " id : #{id}<br/>"
+ " name : #{name}<br/>"
+ " gender : #{gender->map(female:女, else:男)}<br/>"
+ " pic : <img src='#{pic}' align='top'/><br/>"
+ " summary: #{details->sub(20, l, >>>)}<br/>"
+ " details: #{details}"
+ "</pre>"
); var output = StrUtil.simpleFormat(temp, params, {
getWelcome : function(key, val){
return "hello " + val + ' current time is :' + new Date();
}
}); document.getElementById('div1').innerHTML = output;
};