昨晚写的那个js模版引擎有不少bug,比如有些分隔符不支持,ie下有bug,并且还用了遭不少人唾弃的with,今晚又进行了一下改善,提高了分隔符的自由度,避开了with的使用,
修复了在ie下的bug(这个主要是由转义字符引起的bug,IE7下任然错误^_^),好了不多说了,直接看demo吧!
<div>hust_小C的模版引擎 <h2>对象遍历</h2> { { for(var i in data.a){ }} <li>{ {=i}}:{ {=data.a[i]}}</li> { { } }} <h2>If else 解析</h2> { {if(data.b==100){}} b的值为:{ {=data.b}} { {}else{ }} b的值不满足if条件 { { } }} <h2>表格解析</h2> <table style="background:red;color:#fff;" _mce_style="background: #990033;"> <tr>歌曲名</th><th>歌手</th><th>歌曲链接</th></tr> { { for(var i=0,l=data.song.length;i<l;i++){ }} <tr><td>{ {=data.song[i].songname}}</td><td>{ {=data.song[i].singer}}</td><td><a href="{ {=data.song[i].url}}" _mce_href="{ {=data.song[i].url}}">{ {=data.song[i].url}}</a></td></tr> { { } }} </table> <h2>图像解析</h2> { { for(var i=0,l=data.url.length;i<l;i++){ }} <img src="{ {=data.url[i]}}"> { { } }} </div>
模版解析核心代码
/** * @author hust_小C * email:hustcoolboy@gmail.com */var dom = { quote: function (str) { str = str.replace(/[\x00-\x1f\\]/g, function (chr) { var special = metaObject[chr]; return special ? special : '\\u' + ('0000' + chr.charCodeAt(0).toString(16)).slice(-4) }); return str.replace(/"/g, '\\"') ; } }, metaObject = { '\b': '\\b', '\t': '\\t', '\n': '\\n', '\f': '\\f', '\r': '\\r', '\\': '\\\\' };//上边的dom来自司徒正美(function(w){ w.Template=Template||{}; function Template(options){ return this instanceof arguments.callee?this.init(options):new arguments.callee(options); } Template.prototype={ init:function(options){ this.tpl=options.tpl;//待解析的模版 this.target=options.target||options.tpl;//解析后渲染的模板dom this.tplcontent=dom.quote(options.tpl.text||options.tpl.value); this.left=options.left||"{ {";//左分隔符 this.right=options.rigth||"}}";//右分隔符 this.namespace=options.namespace||"data";//编译生成的函数,里边所用变量的环境,即模版中所用变量的执行环境 this.body=[]; this.compiled="";//编译生成的函数 this.data=options.data; }, parse:function(){ var self=this; this.tplcontent.split(new RegExp('(?='+this.left+')|('+this.right+')')).filter(function(k,v){ return !(new RegExp(self.right)).test(v); }).each( function(k,v){ if((new RegExp('^'+self.left)).test(v)){ if(new RegExp('^'+self.left+'\s*=').test(v)){ self.body.push(v.replace(new RegExp('^'+self.left+'\s*=(.*)'),'\ttemp.push($1);\n').replace(/\\n/g,'')); }else{ self.body.push(v.replace(new RegExp('^'+self.left+'\s*(.*)'),'$1\n').replace(/\\n/g,'')); } } else {self.body.push('\ttemp.push(\"'+v.replace(/[\n\t]/g,'')+'\");\n');} }) return this.body.join(""); }, compile:function(){ if(!this.compiled){ this.compiled=new Function(this.namespace,'var temp=[];\n'+this.parse()+'\n return temp.join("");'); } return this.compiled; }, render:function(){ this.target.innerHTML=this.compile()(this.data); } }})(this); Array.prototype.filter=function(fn){ var temp=[]; for(var i=0,l=this.length;i