sychelTemplate 简介

0、sychelTemplate希望创造一个用户觉得“简单好用”的JS模板引擎

注:等不及可以直接点左侧导航中的”C、使用举例“,demo即刻试用。
1、应用场景:

前端使用的模板系统 或 后端Javascript环境发布页面
2、功能概述:

提供一套模板语法,用户可以写一个模板区块,每次根据传入的数据,
生成对应数据产生的HTML片段,渲染不同的效果。
3、特性:

1、语法简单,学习成本极低,开发效率提升很大,性价比较高(使用Javascript原生语法);
2、默认HTML转义(防XSS攻击),并且支持包括URL转义等多种转义;
3、变量未定义自动输出为空,防止页面错乱;
4、功能强大,如分隔符可自定等多种功能;

使用举例

//直接复制即可使用,记得要下载sychelTemplate.js
//index.html
<!doctype html>
<html>
<head>
<meta charset="utf-8"/>
<title>test</title><!-- 引入sychelTemplate -->
<script type="text/javascript" src="./sychelTemplate.js"></script></head>
<body>
<div id='result'></div><!-- 模板1开始,可以使用script(type设置为text/html)来存放模板片段,并且用id标示 -->
<script id="t:_1234-abcd-1" type="text/html">
<div><!-- 我是注释,语法均为Javascript原生语法,默认分割符为 <% %> ,也可以自定义,参见API部分 --><!-- 输出变量语句,输出title --><h1>title:<%=title%></h1><!-- 判断语句if else--><%if(list.length>1) { %><h2>输出list,共有<%=list.length%>个元素</h2><ul><!-- 循环语句 for--><%for(var i=0;i<5;i++){%><li><%=list[i]%></li><%}%></ul><%}else{%><h2>没有list数据</h2>   <%}%>
</div>
</script>
<!-- 模板1结束 --><!-- 使用模板 -->
<script type="text/javascript">
var data={"title":'欢迎使用sychelTemplate',"list":['test1:默认支持HTML转义,如输出<script>,也可以关掉,语法<:=value> 详见API','test2:','test3:','test4:list[5]未定义,模板系统会输出空']
};//使用sychel.template命名空间
var bt=sychel.template;//可以设置分隔符
//bt.LEFT_DELIMITER='<!';
//bt.RIGHT_DELIMITER='!>';//可以设置输出变量是否自动HTML转义
//bt.ESCAPE = false;//最简使用方法
var html=bt('t:_1234-abcd-1',data);//渲染
document.getElementById('result').innerHTML=html;
</script></body>
</html>

基本用法

0、引入文件:

sychelTemplate使用仅需引入sychelTemplate.js文件,未压缩是考虑大家调错阅读等方便,上线前请自行压缩代码。

如果在nodejs环境中使用,可以通过npm包管理安装

//注意:名称全部小写
npm install sychelTemplate
1、放置模板片段:

页面中,模板块可以放在

<script id='test1' type="text/template">
<!-- 模板部分 --><!-- 模板结束 -->
</script>

或者存放在 中,一般情况设置其CSS样式display:none来隐藏掉textarea,同样用id标识,如:

<textarea id='test2' style='display:none;'>
<!-- 模板部分 --><!-- 模板结束 -->
</textarea>

模板也可以直接存储在一个变量中

var tpl = "<!-- 模板开始 --> 模板内容 <!-- 模板结束 -->";

2、调用引擎方式

(1)、数据结构是一个JSON,如:

var data={title:'sychelTemplate',list:['test data 1','test data 2','test data3']
}

(2)、sychelTemplate占用sychel.template命名空间

//可以付值给一个短名变量使用
var bt = sychel.template;

(3)、方法一:tpl是传入的模板(String类型),可以是模板的id,可以是一个模板片段字符串,传入模板和对应这里写代码片数据返回对应的HTML片段

//方法一:直接传入data,返回编译后的HTML片段
var html0 = sychel.template(tpl,data);  
//或直接传入id即可
var html0 = sychel.template('test1',data);  

方法二:或者可以只传入tpl,这时返回的是一个编译后的函数,可以把这个函数缓存下来,传入不同的data就可以生成不同的HTML片段

//方法二:先不传入data,返回编译后的函数
var fun = sychel.template(tpl);
//或直接传入id即可
var fun = sychel.template('test1');//之后通过改变数据,调用缓存下来的函数,产生不同的HTML片段
var html1 = fun(data1);
var html2 = fun(data2);

(4)、最后将他们插入到一个容器中即可

document.getElementById('result0').innerHTML=html0;
document.getElementById('result1').innerHTML=html1;
document.getElementById('result2').innerHTML=html2;

3、模板基本语法(默认分隔符为<% %>,也可以自定义)

分隔符内语句为js语法,如:

<% var test = function(){//函数体
};
if(1){}else{};
function testFun(){return;
};
%>

假定事先设置数据为

var data={title:'sychelTemplate',list:['test1<script>','test2','test3']
}

注释

<!-- 模板中可以用HTML注释 -->  或  <%* 这是模板自带注释格式 *%><% //分隔符内支持JS注释  %>
输出一个变量//默认HTML转义,如果变量未定义输出为空
<%=title%>  //不转义
<%:=title%> 或 <%-title%>//URL转义,UI变量使用在模板链接地址URL的参数中时需要转义
<%:u=title%>//UI变量使用在HTML页面标签onclick等事件函数参数中需要转义
//“<”转成“&lt;”、“>”转成“&gt;”、“&”转成“&amp;”、“'”转成“\'”
//“"”转成“\&quot;”、“\”转成“\\”、“/”转成“\/”、\n转成“\n”、\r转成“\r”
<%:v=title%>//HTML转义(默认自动)
<%=title%> 或 <%:h=title%>

判断语句

<%if(list.length){%><h2><%=list.length%></h2>
<%}else{%><h2>list长度为0<h2>
<%}%>

循环语句

<%for(var i=0;i<list.length;i++){%><li><%=list[i]%></li>
<%}%>

4、不推荐使用功能

用户可以自定义分隔符,默认为 <% %>,如:

//设置左分隔符为 <!
sychel.template.LEFT_DELIMITER='<!';//设置右分隔符为 <!
sychel.template.RIGHT_DELIMITER='!>';
自定义默认输出变量是否自动HTML转义//设置默认输出变量是否自动HTML转义,true自动转义,false不转义
sychel.template.ESCAPE = false;

D、性能相关数据
前端模板引擎在传统桌面电脑的浏览器端编译模板并渲染页面,无较大的性能开销。但在移动端上面,性能数据较为重要,故发布移动端性能数据列表,希望能够给各位开发者提供一个参考。

总结:编译执行时间(前端模版编译以及json被转换为html字符串的时间)范围约在10~90毫秒,大部分集中在20~60毫秒之间。Dom渲染时间(html字符串通过dom.innerHTML被插入到div里的时间)范围约在40~160毫秒,大部分集中在50~130毫秒之间。

源码

/*** @介绍:Sychel简单好用的Javascript模板引擎 1.0.6版本,这套模板机制的语法和JavaScript原生* 的语法一致,在<%%>中进行书写,注意的是<%=%>是变量输出,<%:=%>是带转义的输出。* @排错:模板语言的错误,F12工具不能进行检查,所以只能通过alert();来打印,所以这个问题我也在思考。* @param str{String} dom结点ID,或者模板string* @param data{Object} 需要渲染的json对象,可以为空。当data为{}时,仍然返回html。* @return 如果无data,直接返回编译后的函数;如果有data,返回html。* @author Sychel* @email  y921105@126.com
*///取得浏览器环境的Sychel命名空间,非浏览器环境符合commonjs规范exports出去//修正在nodejs环境下,采用Sychel.template变量名var Sychel = typeof module === 'undefined' ? (window.Sychel = window.Sychel || {}) : module.exports;//模板函数(放置于Sychel.template命名空间下)Sychel.template = function(str, data){//检查是否有该id的元素存在,如果有元素则获取元素的innerHTML/value,否则认为字符串为模板var fn = (function(){//判断如果没有document,则为非浏览器环境if(!window.document){return bt._compile(str);};//HTML5规定ID可以由任何不包含空格字符的字符串组成var element = document.getElementById(str);if (element) {//取到对应id的dom,缓存其编译后的HTML模板函数if (bt.cache[str]) {return bt.cache[str];};//textarea或input则取value,其它情况取innerHTMLvar html = /^(textarea|input)$/i.test(element.nodeName) ? element.value : element.innerHTML;return bt._compile(html);}else{//是模板字符串,则生成一个函数//如果直接传入字符串作为模板,则可能变化过多,因此不考虑缓存return bt._compile(str);};})();//有数据则返回HTML字符串,没有数据则返回函数 支持data={}的情况var result = bt._isObject(data) ? fn( data ) : fn;fn = null;return result;};//取得命名空间 Sychel.templatevar bt = Sychel.template;//标记当前版本bt.versions = bt.versions || [];bt.versions.push('1.0');//缓存  将对应id模板生成的函数缓存下来。bt.cache = {};//自定义分隔符,可以含有正则中的字符,可以是HTML注释开头 <! !>bt.LEFT_DELIMITER = bt.LEFT_DELIMITER||'<%';bt.RIGHT_DELIMITER = bt.RIGHT_DELIMITER||'%>';//自定义默认是否转义,默认为默认自动转义bt.ESCAPE = true;//HTML转义bt._encodeHTML = function (source) {return String(source).replace(/&/g,'&amp;').replace(/</g,'&lt;').replace(/>/g,'&gt;').replace(/\\/g,'\').replace(/"/g,'&quot;').replace(/'/g,''');};//转义影响正则的字符bt._encodeReg = function (source) {return String(source).replace(/([.*+?^=!:${}()|[\]/\\])/g,'\\$1');};//转义UI UI变量使用在HTML页面标签onclick等事件函数参数中bt._encodeEventHTML = function (source) {return String(source).replace(/&/g,'&amp;').replace(/</g,'&lt;').replace(/>/g,'&gt;').replace(/"/g,'&quot;').replace(/'/g,''').replace(/\\\\/g,'\\').replace(/\\\//g,'\/').replace(/\\n/g,'\n').replace(/\\r/g,'\r');};//将字符串拼接生成函数,即编译过程(compile)bt._compile = function(str){var funBody = "var _template_fun_array=[];\nvar fn=(function(__data__){\nvar _template_varName='';\nfor(name in __data__){\n_template_varName+=('var '+name+'=__data__[\"'+name+'\"];');\n};\neval(_template_varName);\n_template_fun_array.push('"+bt._analysisStr(str)+"');\n_template_varName=null;\n})(_template_object);\nfn = null;\nreturn _template_fun_array.join('');\n";return new Function("_template_object",funBody);};//判断是否是Object类型bt._isObject = function (source) {return 'function' === typeof source || !!(source && 'object' === typeof source);};//解析模板字符串bt._analysisStr = function(str){//取得分隔符var _left_ = bt.LEFT_DELIMITER;var _right_ = bt.RIGHT_DELIMITER;//对分隔符进行转义,支持正则中的元字符,可以是HTML注释 <!  !>var _left = bt._encodeReg(_left_);var _right = bt._encodeReg(_right_);str = String(str)//去掉分隔符中js注释.replace(new RegExp("("+_left+"[^"+_right+"]*)//.*\n","g"), "$1")//去掉注释内容  <%* 这里可以任意的注释 *%>//默认支持HTML注释,将HTML注释匹配掉的原因是用户有可能用 <! !>来做分割符.replace(new RegExp("<!--.*?-->", "g"),"").replace(new RegExp(_left+"\\*.*?\\*"+_right, "g"),"")//把所有换行去掉  \r回车符 \t制表符 \n换行符.replace(new RegExp("[\\r\\t\\n]","g"), "")//用来处理非分隔符内部的内容中含有 斜杠 \ 单引号 ‘ ,处理办法为HTML转义.replace(new RegExp(_left+"(?:(?!"+_right+")[\\s\\S])*"+_right+"|((?:(?!"+_left+")[\\s\\S])+)","g"),function (item, $1) {var str = '';if($1){//将 斜杠 单引 HTML转义str = $1.replace(/\\/g,"\").replace(/'/g,''');while(/<[^<]*?'[^<]*?>/g.test(str)){//将标签内的单引号转义为\r  结合最后一步,替换为\'str = str.replace(/(<[^<]*?)'([^<]*?>)/g,'$1\r$2')};}else{str = item;}return str ;});str = str //定义变量,如果没有分号,需要容错  <%var val='test'%>.replace(new RegExp("("+_left+"[\\s]*?var[\\s]*?.*?[\\s]*?[^;])[\\s]*?"+_right,"g"),"$1;"+_right_)//对变量后面的分号做容错(包括转义模式 如<%:h=value%>)  <%=value;%> 排除掉函数的情况 <%fun1();%> 排除定义变量情况  <%var val='test';%>.replace(new RegExp("("+_left+":?[hvu]?[\\s]*?=[\\s]*?[^;|"+_right+"]*?);[\\s]*?"+_right,"g"),"$1"+_right_)//按照 <% 分割为一个个数组,再用 \t 和在一起,相当于将 <% 替换为 \t//将模板按照<%分为一段一段的,再在每段的结尾加入 \t,即用 \t 将每个模板片段前面分隔开.split(_left_).join("\t");//支持用户配置默认是否自动转义if(bt.ESCAPE){str = str//找到 \t=任意一个字符%> 替换为 ‘,任意字符,'//即替换简单变量  \t=data%> 替换为 ',data,'//默认HTML转义  也支持HTML转义写法<%:h=value%>  .replace(new RegExp("\\t=(.*?)"+_right,"g"),"',typeof($1) === 'undefined'?'':Sychel.template._encodeHTML($1),'");}else{str = str//默认不转义HTML转义.replace(new RegExp("\\t=(.*?)"+_right,"g"),"',typeof($1) === 'undefined'?'':$1,'");};str = str//支持HTML转义写法<%:h=value%>  .replace(new RegExp("\\t:h=(.*?)"+_right,"g"),"',typeof($1) === 'undefined'?'':Sychel.template._encodeHTML($1),'")//支持不转义写法 <%:=value%>和<%-value%>.replace(new RegExp("\\t(?::=|-)(.*?)"+_right,"g"),"',typeof($1)==='undefined'?'':$1,'")//支持url转义 <%:u=value%>.replace(new RegExp("\\t:u=(.*?)"+_right,"g"),"',typeof($1)==='undefined'?'':encodeURIComponent($1),'")//支持UI 变量使用在HTML页面标签onclick等事件函数参数中  <%:v=value%>.replace(new RegExp("\\t:v=(.*?)"+_right,"g"),"',typeof($1)==='undefined'?'':Sychel.template._encodeEventHTML($1),'")//将字符串按照 \t 分成为数组,在用'); 将其合并,即替换掉结尾的 \t 为 ');//在if,for等语句前面加上 '); ,形成 ');if  ');for  的形式.split("\t").join("');")//将 %> 替换为_template_fun_array.push('//即去掉结尾符,生成函数中的push方法//如:if(list.length=5){%><h2>',list[4],'</h2>');}//会被替换为 if(list.length=5){_template_fun_array.push('<h2>',list[4],'</h2>');}.split(_right_).join("_template_fun_array.push('")//将 \r 替换为 \.split("\r").join("\\'");return str;};

JS模板引擎sychelTemplate相关推荐

  1. js模板引擎art template数组渲染的方法

    转载:js模板引擎art template数组渲染的方法 JavaScript 模板引擎作为数据与界面分离工作中最重要一环,越来越受开发者关注,模板引擎种类也是五花八门,我就说几个安全性高.错误处理调 ...

  2. js模板引擎 之handlebars.js

    最近在接触郑州知识库,里面使用到的技术是值得自己学习的. 该项目前端使用的是handlebars.js模板引擎框架.模板引擎框架用于数据与结构分离的思想,实现页面动态分离的效果. 1.为什么使用模板引 ...

  3. 解决laytpl.js模板引擎插件加载模板后无法获取模板中的元素id等内容

    一.问题描述 在页面中使用laytpl.js模板引擎,在页面加载后无法使用jquery获取模板中的html元素,以下是图片和代码: 在添加或修改完毕后重新加载页面,不能使用jquery获取模板中的ht ...

  4. js模板引擎渐进--后记

    至此,算是完成了一个系列了. 本来是想写的更详细的,但是太详细每次说的东西就少的可怜. 在学习的过程中,每次的改进改动博主都是复制一个新的文件进行,整个有二十多篇,中间有很多小细节的东西,集中在 ea ...

  5. js模板引擎Nunjucks

    js模板引擎Nunjucks Nunjucks中文文档

  6. js模板引擎渐进--if/else(7)

    有了 each 的经验后,要实现 if/else 这种指令就简单了-------在  case '}' 处对 varcode 进行指令的判断即可. 模板代码: {if data.value==1}&l ...

  7. 简单实用的js模板引擎

    转自:微点阅读  https://www.weidianyuedu.com 不足50行的js模板引擎,支持各种js语法: <script id="test_list" typ ...

  8. doT.js 模板引擎的使用

    dot.js是一个模板框架,在web前端使用. dot.js作为模板引擎, 主要的用途就是,在写好的模板上,放进数据,生成含有数据的html代码. 这是很简单的web前端模板框架, 简单说几个东西,你 ...

  9. JS模板引擎handlerbars入门

    handlebars   -- 前端的模板引擎 <!DOCTYPE html> <html lang="en"> <head><meta ...

最新文章

  1. run as gradle test,未执行@Test中的内容(待解决)
  2. 引用数据类型的深拷贝
  3. php smtp报文_PHP 使用 SMTP 发送邮件教程(PEAR Mail 包)
  4. 《线性代数及其应用》
  5. tomcat jsvc java_opts_Tomcat 学习笔记(2) - 使用 jsvc 启动tomcat
  6. python-函数的使用 0222
  7. java stub_Java Stub 研究学习(2)
  8. android 按钮变形动画,android-动画切换按钮
  9. 用jsp编写一个猜26个小写英文字母的web小游戏
  10. 信息和信息技术的概念,发展和应用
  11. 离职原因之3B分类问题
  12. Java【汉诺塔问题】详细图文解析, 包教包会
  13. WebGIS地图相关学习笔记
  14. 技术专栏|多旋翼飞行器振动机理分析和减振设计
  15. python升级到3.7版本安装pyaudio
  16. matlab总路径最短问题,最短路径问题(急)
  17. C++编程练习 计算一元二次方程组解判断是否测试过三种情况
  18. 惯性坐标系、物体坐标系、世界坐标系
  19. windows 安装chatterbot
  20. Java Web 程序设计期末复习重要知识点总结

热门文章

  1. QTextBrowser显示图片(图片文字对齐)
  2. Xcode7 Cocoapods 插件用法
  3. 【全网最全】JSR303参数校验与全局异常处理(从理论到实践别用if判断参数了)
  4. Bitvise Tunnelier秘钥链接阿里云Linux服务器
  5. html如何携带参数自动跳转页面
  6. HTML修改单选框多选框按钮样式
  7. HTML实体的编码和解码
  8. delphi 数字转字符串补全
  9. Oracle数据库语句总结
  10. Twincat3 启动报错