现代浏览器性能越来越好,不充分利用浏览器真的有点可惜,因此也出了很多JavaScript框架,将原本在服务端处理的渲染过程,放到了浏览器端来减少WEB服务端的压力。
今天介绍一种简单的实现,可以用JS在浏览器端,类似服务器端JSP一样的形式渲染html页面。
先看一个页面代码:
<html>
<body>
<div id="J_Div">
<h3><%=title%></h3>
<%
var c = 0;
for (var i = 0 ; i < itemList.length; i++) {
c++;
%>
<% if( c % 2 == 0) { %>
abcdefg
<% } %>
<% if (i==1) { %>
<span style="color:red"> <%=itemList[i].name%> </span>
<%} else {%>
<span> <%= itemList[i].name + 'AAA' %> </span>
<%}%>
<br/>
<%}%>
</div>
</body>
<script type="text/javascript" src="jstemplate.js"></script>
<script>
var data = {title:'title1',itemList:[{name:'abc1'},{name:'abc2'},{name:'abc3'}]};
new JSTemplate().render(data,'J_Div');
</script>
</html>
是否是感觉曾相识,初看一下像是JSP页面,但是其实它是一个在浏览器端渲染的页面。
原理是怎么样的呢?
其实学过JSP的人都知道,JSP其实最终会转换成JAVA代码,JavaScript的模板渲染原理类似的,最终也是将模板内容转换成JavaScript代码。只要生成合适的函数即可:
代码如下:
/**
* csdn - zhfit
*/
(function(){
var JSTemplate = function() {
};
JSTemplate.prototype = {
_prepareTemplate: function(template) {
var tempLiteral = template.replace(/</g, "<").replace(/>/g, ">").replace(/<%/g,"<$").replace(/%>/g,"$>");
return tempLiteral.split("$");
},
_createDynaFun: function(tempSegment) {
var func = new Array();
func.push("var JS_TEMP_FUN=function(_context,out){");
func.push("with(_context){");
var prevChar = '';
var nextChar = '';
while (tempSegment.length > 0) {
var stmt = tempSegment.shift();
var lastChar = stmt.charAt(stmt.length-1);
nextChar = stmt.charAt(0);
if (stmt.charAt(0) == '>') {
stmt = stmt.slice(1);
}
if (stmt.charAt(stmt.length-1) == '<') {
stmt = stmt.slice(0,-1);
}
if (stmt.length > 0) {
if(prevChar == '<') {
if (nextChar == '=') {
func.push('out.push(' + stmt.substring(1).replace(/\\/g, '\\\\').replace(/\n/g, '\\n').replace(/"/g, '\\"') + ');');
} else {
func.push(stmt);
}
} else {
func.push('out.push(\'' + stmt.replace(/\\/g, '\\\\').replace(/\n/g, '\\n').replace(/"/g, '\\"') + '\');');
}
}
prevChar = lastChar;
}
func.push("}};JS_TEMP_FUN");
return eval(func.join(""));
},
render : function (data, id) {
var tempEl = document.getElementById(id);
var tempSeg = this._prepareTemplate(tempEl.innerHTML);
var tempFun = this._createDynaFun(tempSeg);
var pageOut = new Array();
tempFun(data, pageOut);
tempEl.innerHTML = pageOut.join("");
}
};
window.JSTemplate = JSTemplate;
})();
是不是发现跟JSP的原理很类似?最终是转换成一个拼接字符串的函数而已。