javascript模版引擎-tmpl 的精简及bug修正
展开/收缩在基于MVC框架开发的web app中,js模板引擎显得特别重要,只需一个模板文本加一段json数据,mix一下,内容就出来了,以往都是用mustache.js, 这里记录一下项目同事介绍一个超精简的模板引擎-tmpl ,对对于mustache.js的单独的模板语法,这个引擎亲切许多,因为可以直接使用js原生的语法,像for switch if,之类。原作为jquery的作者John Resig 开发,详细博客地址, 另有国内某牛人性能改进版,详细见 博文 ,但使用之后,发现还是有点问题,先贴下完整代码:
/**
* 微型模板引擎 tmpl 0.2
* 0.2 更新:
* 1. 修复转义字符与id判断的BUG
* 2. 放弃低效的 with 语句从而最高提升3.5倍的执行效率
* 3. 使用随机内部变量防止与模板变量产生冲突
* @example
* 方式一:在页面嵌入模板
* <scriptt type="text/tmpl" id="tmpl-demo">
* <ol title="<%=name%>">
* < % for (var i = 0, l = list.length; i < l; i ++) { %>
* <li>< %=list[i]%></li>
* < % } %>
* </ol>
* </scriptt>
* tmpl('tmpl-demo', {name: 'demo data', list: [202, 96, 133, 134]})
*
* 方式二:直接传入模板:
* var demoTmpl =
* '<ol title="<%=name%>">'
* + '< % for (var i = 0, l = list.length; i < l; i ++) { %>'
* + '<li>< %=list[i]%></li>'
* + '< % } %>'
* +'</ol>';
* var render = tmpl(demoTmpl);
* render({name: 'demo data', list: [202, 96, 133, 134]});
*
* 这两种方式区别在于第一个会自动缓存编译好的模板,
* 而第二种缓存交给外部对象控制,如例二中的 render 变量。
* @blog http://www.planeart.cn/?p=1594
* @see http://ejohn.org/blog/javascript-micro-templating/
* @param {String} 模板内容或者装有模板内容的元素ID
* @param {Object} 附加的数据
* @return {String} 解析好的模板
*/
var tmpl = (function (cache, $) {
return function (str, data) {
var fn = !/\W/.test(str)
? cache[str] = cache[str]
|| tmpl(document.getElementById(str).innerHTML)
: function (data) {
var i, variable = [$], value = [[]];
for (i in data) {
variable.push(i);
value.push(data[i]);
};
return (new Function(variable, fn.$))
.apply(data, value).join("");
};
fn.$ = fn.$ || $ + ".push('"
+ str.replace(/\\/g, "\\\\")
.replace(/[\r\t\n]/g, " ")
.split("< %").join("\t")
.replace(/((^|%>)[^\t]*)'/g, "$1\r")
.replace(/\t=(.*?)%>/g, "',$1,'")
.split("\t").join("');")
.split("%>").join($ + ".push('")
.split("\r").join("\\'")
+ "');return " + $;
return data ? fn(data) : fn;
}})({}, '$' + (+ new Date));
Der's Blog