javascript模板系统 ejs v8
ejsv8对ejsv7进行大量简化与提速工作,本版本进行了以下改进。
- 去掉去掉参数多态化,现在只有两个参数。第一个参数为script标签的ID,第二个参数对数据对象
- 去掉@标识符,网友反映这东西很怪
- 去掉远程模板支持,因为怎么远程也一定要同域才行,要不AJAX获取不到,鸡肋。以后模板统一写到type为"text/html"的scrpt元素中。
- 优化quote函数。网上有许多JS模板都是直接用正则进行全文转义,但怎么说也不比上quote函数安全。
- 使用apply对传参进行优化。indexOf判定优化。
- 代码量由140行缩减到75行。
//dom.ejs v8 by 司徒正美 //http://www.cnblogs.com/rubylouvre/archive/2011/03/03/1969718.html ; (function(DOC){ this.dom = { quote : window.JSON && JSON.stringify || String.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, '\\"') + '"'; } } if(!String.prototype.trim){ String.prototype.trim = function(){ return this.replace(/^[\s\xa0]+|[\s\xa0]+$/g, ''); } } var metaObject = { '\b': '\\b', '\t': '\\t', '\n': '\\n', '\f': '\\f', '\r': '\\r', '\\': '\\\\' }, _startOfHTML = "\t__views.push(", _endOfHTML = ");\n", sRight = "&>", rLeft = /\s*<&\s*/, rRight = /\s*&>\s*/ var ejs2 = dom.ejs = function(id,data){ if(!ejs2[id]){ var rleft = rLeft, rright = rRight, sright = sRight,startOfHTML = _startOfHTML, endOfHTML = _endOfHTML, str , logic, el = DOC.getElementById(id); if (!el) throw "can not find the target element"; str = el.text; var arr = str.trim().split(rleft), temp = ["var __views = [];\n"],i = 0,n = arr.length,els,segment; while(i < n){//逐行分析,以防歧义 segment = arr[i++]; els = segment.split(rright); if(~segment.indexOf(sright) ){//这里不使用els.length === 2是为了避开IE的split bug switch (els[0].charAt(0)) { case "="://处理后台返回的变量(输出到页面的); logic = els[0].substring(1); temp.push(startOfHTML, logic, endOfHTML); break; case "#"://处理注释 break; default://处理逻辑 logic = els[0]; temp.push(logic, "\n"); } //处理静态HTML片断 els[1] && temp.push(startOfHTML,dom.quote.call(null,els[1]), endOfHTML);//转义 }else{ //处理静态HTML片断 temp.push(startOfHTML, dom.quote.call(null,els[0]),endOfHTML); } } var keys = [], values = []; for( i in data){ keys.push(i); values.push(data[i]); } keys.push(temp.concat(" return __views.join('');").join("")) return (ejs2[id] = Function.apply(0,keys)).apply(0,values); } var vals = [] for( i in data){ vals.push(data[i]); } return ejs2[id].apply(0,vals); } })(document);
用法var str = dom.ejs(id,data)。第一个参数为script标签的ID,第二个参数对数据对象。str为处理好的HTML片断字符,直接el.innerHTML = str就行。界定符依旧是<&与>&,如果<紧跟着的是=号,说明这后面的部要输出页面,若是#号,则是注释,不输出页面,其他部分与ASP的使用方法一样。
下面是与糖饼的tmplv2,公认最快的模板YayaTemplate,ejsv7的速度比较,为了公平起见,ejsv7,v8都去掉缓存功能。
糖饼与yaya的都是模仿jQ作者John Resig 的思路,通过环则反复对界定符进行替换,对HTML部分进行转义,但我不相信那一点正则完全实现转义,可以正则构建的代码结构也缺乏对各种特殊情况的处理,要不John Resig就不会搞一个更长更庞大的jquery-tmpl。比如yaya的如果第一行是{% list[0].index%}就报错了,可证一个。如果页面结构更复杂一点,其缺陷就暴露得更多。
更新日志
v1 默认界定符为<% %>,当然也可以自定义界定符,只支持当前页面的script元素做模板 http://www.cnblogs.com/rubylouvre/archive/2010/08/10/1796383.html v2 改进算法提速,比John Resig的 Micro-Templating模板更能应对复杂的模板 http://www.cnblogs.com/rubylouvre/archive/2010/08/22/1805914.html v3 http://www.cnblogs.com/rubylouvre/archive/2010/08/25/1807789.html 增添了局部模板功能 v4 http://www.cnblogs.com/rubylouvre/archive/2010/08/31/1813122.html 对v3的结构进行优化,支持远程的独立文件做模板 v5 http://www.cnblogs.com/rubylouvre/archive/2010/08/31/1813122.html 尝试新的算法 v6 http://www.cnblogs.com/rubylouvre/archive/2010/10/05/1841933.html 更新默认界定符为<& &>,添加新的操作符<&~,对数据源的第一层属性名添加@前缀 v7 对参数进行多态化,因ejs天生支持模板的相互调用便去除<&:与<&~操作符 v8 简化与提速 tmpl02 ejsv7 ejsv8 yaya opera11.52 271.9 258.65 253 200.45 chrome14 380.6 373.85 367.95 402.05 firefox7.01 235.7 166.2 174.25 151.5 IE9 432.25 489.6 468.5 394.1 safari 5 332.35 292.45 292.05 265.15
机器瞎学/数据掩埋/模式混淆/人工智障/深度遗忘/神经掉线/计算机幻觉/专注单身二十五年