應(yīng)用場(chǎng)景
前端如angular 和 vue 都有模板指令愁憔,后端express也可以配合使用多種模塊引擎,這些大部分都是模板渲染
要點(diǎn)
將模塊按照規(guī)則合成一個(gè)Function實(shí)例逆瑞,然后調(diào)用
例子,實(shí)現(xiàn)模板引擎ejs的for功能
html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>模板渲染</title>
<style>
</style>
</head>
<body>
<div id="list">
</div>
<!--
模板放置的地方伙单,由于設(shè)置了type获高,所以瀏覽器不會(huì)把這當(dāng)作JavaScript來(lái)運(yùn)行
-->
<script type="text/template" id="templs">
<ul>
<% for(var i in obj){ %>
<li><%= obj[i].text %>:<%= obj[i].status %></li>
<% } %>
</ul>
</script>
<script src="mytempltes.js"></script>
<script>
new Template({
el:"list",// 渲染節(jié)點(diǎn)
tem:"templs", // 模板節(jié)點(diǎn)
data:[
{
text:"大前端",status:"火熱"
},
{
text:"大前端2",status:"火熱2"
}
]
});
</script>
</body>
</html>
mytempltes.js
(function(win,factory){
win.Template = factory;
})(this,function(options){//options就是傳入的對(duì)象
//匹配指定的字符:A:<% ... %> B:<%= %>
var matcher = /<%=([\s\S]+?)%>|<%([\s\S]+?)%>|$/g;//這個(gè)正則不是去匹配,而是根據(jù)正則替換
var el = document.getElementById(options.el);
var tem = document.getElementById(options.tem).innerHTML;
var data = options.data;
var escaper = /\\|'|\r|\n|\t|\u2028|\u2029/g;//特殊字符列表
//空格:$nbsp; &glt;....
var escapers = {//匹配需要匹配的字段吻育,替換為指定的字段
"'":"'",
"\\":"\\",
"\r":"r",
"\n":"n",
"\t":"t",
"\u2028":"u2028",
"\u2029":"u2029"
}
//XSS攻擊:傳入一些特殊的字符念秧,以混淆JS,傳入進(jìn)來(lái)布疼,導(dǎo)致程序錯(cuò)誤或者出現(xiàn)Bug
var template = function(text,data){//處理業(yè)務(wù)邏輯
/*
由于語(yǔ)法特殊摊趾,如果單純的通過(guò)if或者其他判斷,肯定不能達(dá)到理想的效果
就需要根據(jù)已有的模板字符來(lái)動(dòng)態(tài)創(chuàng)建方法
*/
var index = 0;
var function_body = "var dataHtml = '';";
function_body += "dataHtml += '";
text.replace(matcher,function(match,interlpolate,evaluate,offset){
/*
match:被匹配的模板字符
interlpolate:已經(jīng)替換的字符
evaluate:已經(jīng)替換的字符
offset:被替換字符的下標(biāo)位置
指定字符串的位置:text.slice(起始位置游两,結(jié)束位置)
*/
function_body += text.slice(index,offset)
.replace(escaper,function(match){
return '\\' + escapers[match];//因?yàn)闆](méi)有指定的字符
});
if(evaluate){
function_body += "';"+evaluate+"dataHtml += '";
}
if(interlpolate){
function_body += "' + " + interlpolate + " + '";
}
index = offset + match.length;//已有的長(zhǎng)度+字符的長(zhǎng)度 = 下一個(gè)的長(zhǎng)度
return match;
});
function_body += "';return dataHtml";
//此時(shí)render已經(jīng)是一個(gè)動(dòng)態(tài)的方法了
var render = new Function('obj',function_body);//通過(guò)new Functionn得到一個(gè)通過(guò)字符串生成的動(dòng)態(tài)方法
return render(data);
}
el.innerHTML = template(tem,data);
});
如果覺(jué)得文章對(duì)你有點(diǎn)用的話砾层,麻煩拿出手機(jī),這里有一個(gè)你我都有的小福利(每天一次): 打開(kāi)支付寶首頁(yè)搜索“8601304”贱案,即可領(lǐng)紅包肛炮。謝謝支持