首先是一个自执行的匿名函数。
(function() { })();
然后定义了一个window的属性暴露出来供调用。
(function() { this.tmpl = function tmpl(str, data) { } })();
这里的this就是window对象,str是用户传进来的字符串,模板的id或者是模板字符串(见下文),data是渲染模板的数据。
函数中首先做个判断,判断一下str是不是模板的id
!/\W/.test(str)
正则表达式中,\W和\w表示的相反的概念。\w表示字母数字和下划线,自然\W表示非字母非数字非下划线,也就是说如果传进的字符串是数字字母和下划线的组合,就是id,否则就是要解析的模板字符串。
代码中用问号操作符
!/\W/.test(str) ? /*str是id*/ : /*str是模板字符串*/
如果是id,首选看一下之前有没有缓存过,如果有,直接用,否则取出id的innerHTML,进行解析,同时不要忘了也要放到缓存里。
cache[str] = cache[str] || tmpl(document.getElementById(str).innerHTML)
接下来,就是模板字符串的解析了。模板字符串类似以下格式:
<% for ( var i = 0; i < users.length; i++ ) { %> <li><a href="<%=users[i].url%>"><%=users[i].name%></a></li> <% } %>
不管是通过script标签还是直接传进去,最后都是解析这种格式。
解析的函数使用了Function构造函数:
new Function("obj", "var p=[],print=function(){p.push.apply(p,arguments);};" + // Introduce the data as local variables using with(){} "with(obj){p.push(‘" + // Convert the template into pure JavaScript str .replace(/[\r\t\n]/g, " ") .split("<%").join("\t") .replace(/((^|%>)[^\t]*)‘/g, "$1\r") .replace(/\t=(.*?)%>/g, "‘,$1,‘") .split("\t").join("‘);") .split("%>").join("p.push(‘") .split("\r").join("\\‘") + "‘);}return p.join(‘‘);");
不太好看的话,改写成这样:
var tmplGenerator = function(obj) { var p = [], print = function() { p.push.apply(p, arguments); }; with(obj) { var s = str .replace(/[\r\t\n]/g, " ") .split("<%").join("\t") .replace(/((^|%>)[^\t]*)‘/g, "$1\r") .replace(/\t=(.*?)%>/g, "‘,$1,‘") .split("\t").join("‘);") .split("%>").join("p.push(‘") .split("\r").join("\\‘"); p.push(s); } return p.join(‘‘); }
未完待续。。。
时间: 2024-10-12 23:30:58