之前的项目中用到了artTemplate模板,感觉挺有意思,于是查看相关资料,自己动手写了个简单地template模板插件。虽然会有一些不足,但也是自己的一番心血。主体代码如下

        /*
* 一个简单地template模板语法写法
*/
!function () {
"use strict";
/*
*tpl为传入的模板内容,data为数据
*/
function template(tpl, data) {
/*如果传入的是元素,则获取他的innerHTML赋值给他本身*/
if (tpl.tagName) {
tpl = tpl.innerHTML;
}
/*将tpl中的"转义*/
tpl = tpl.replace(/"/g, '\\"');
/*判断使用字符串拼接方式还是使用push方式*/
var isTrim = ''.trim;
/*定义正则表达式
reg: 匹配分隔符<%%>
reg1: 匹配原生js代码
*/
var reg = /<%([^\n]*)%>/g;
var reg1 = /(for|while|do|if|else|switch|case|default|break|continue|{|})/g;
/*定义一个空数组的字符串*/
var str = isTrim ? "var arr = [];" : ["var arr = [];"];
/*定义一个初始的下标,下方会需要*/
var index1 = 0;
/*定义一个接收正则结果的变量*/
var regResult;
while (regResult = reg.exec(tpl)) {
if (isTrim) {
str += 'arr.push("' + tpl.slice(index1, regResult.index).replace(/\s+/g, ' ') + '");';
if (regResult[1].match(reg1)) {
str += regResult[1];
} else {
str += 'arr.push(' + regResult[1] + ');';
}
} else {
str.push('arr.push("');
str.push(tpl.slice(index1, regResult.index).replace(/\s+/g, ' '));
str.push('");');
if (regResult[1].match(reg1)) {
str.push(regResult[1]);
} else {
str.push('arr.push(');
str.push(regResult[1]);
str.push(');');
}
}
index1 = regResult.index + regResult[0].length;
}
if (index1 < tpl.length) {
if (isTrim) {
str += 'arr.push("' + tpl.slice(index1).replace(/\s+/g, ' ') + '");';
} else {
str.push('arr.push("');
str.push(tpl.slice(index1).replace(/\s+/g, ' '));
str.push('");');
}
}
isTrim ? str += 'return arr.join("");' : str.push('return arr.join("");');
isTrim ? '' : str = str.join('');
return new Function(str).call(data);
}
window.template = template;
}();

代码的逻辑很简单,通过isTrim判断是否采用字符串拼接的方法(字符串拼接在IE8一下浏览器中速度很是感人,所以一般采用数组的push方法);之后对获取到的tpl内容进行相关处理,处理成可供js执行的字符串,简单地例子如下:

<ul>
<%for (var i = 0;i < data.arr.length;i++) {%>
<li>
<%for (var j = 0;j < data.arr[i].length;j++) {%>
<a href="javascript:void(0)" data_id="<%data.arr[i][j].id%>">
<%data.arr[i][j].name%>
<span>——</span>
<%data.arr[i][j].value%>
</a><br>
<%}%>
</li>
<%}%>
</ul>

上述代码会被解析成如下字符串代码(在高版本浏览器下):

str = '<ul>';
for (var i = 0;i < data.arr.length;i++) {
str += '<li>';
for (var j = 0;j < data.arr[i][j].length;j++) {
str += '<a href="javascript:void(0)"data_id="' + data.arr[i][j].id + '">' + data.arr[i][j].name + '<span>————</span>' + data.arr[i][j].value + '</a><br>';
}
str += '</li>';
}
str += '</ul>';

最终的字符串放在new Function()内执行(不是很了解这个方法的可以查看w3c,上面有详细的解释),生成需要的字符串。

(reg正则判断还是有问题,刚开始用的是 /<%([^%>]*)%>/g,但是这种匹配规则会不识别类似于<% if (a > b) {%>这种写法,但是有没有找到可以匹配<%开头、%>结尾、中间内容不存在%>的正则匹配规则,所以最终使用了 [^\n]代替,这样就必须每两个<%%>之间要有换行符隔开,但为了照顾到if判断中可能出现的>、<、%,也只好如此了。。。或许可以结合indexOf实现吧。。。)

一个简单地小demo如下

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="ie=edge,chrome=1">
<title>template</title>
<script>
/*
* 一个简单地template模板语法写法
*/
!function () {
"use strict";
/*
*tpl为传入的模板内容,data为数据
*/
function template(tpl, data) {
/*如果传入的是元素,则获取他的innerHTML赋值给他本身*/
if (tpl.tagName) {
tpl = tpl.innerHTML;
}
/*将tpl中的"转义*/
tpl = tpl.replace(/"/g, '\\"');
/*判断使用字符串拼接方式还是使用push方式*/
var isTrim = ''.trim;
/*定义正则表达式
reg: 匹配分隔符<%%>
reg1: 匹配原生js代码
*/
var reg = /<%([^\n]*)%>/g;
var reg1 = /(for|while|do|if|else|switch|case|default|break|continue|{|})/g;
/*定义一个空数组的字符串*/
var str = isTrim ? "var arr = [];" : ["var arr = [];"];
/*定义一个初始的下标,下方会需要*/
var index1 = 0;
/*定义一个接收正则结果的变量*/
var regResult;
while (regResult = reg.exec(tpl)) {
if (isTrim) {
str += 'arr.push("' + tpl.slice(index1, regResult.index).replace(/\s+/g, ' ') + '");';
if (regResult[1].match(reg1)) {
str += regResult[1];
} else {
str += 'arr.push(' + regResult[1] + ');';
}
} else {
str.push('arr.push("');
str.push(tpl.slice(index1, regResult.index).replace(/\s+/g, ' '));
str.push('");');
if (regResult[1].match(reg1)) {
str.push(regResult[1]);
} else {
str.push('arr.push(');
str.push(regResult[1]);
str.push(');');
}
}
index1 = regResult.index + regResult[0].length;
}
if (index1 < tpl.length) {
if (isTrim) {
str += 'arr.push("' + tpl.slice(index1).replace(/\s+/g, ' ') + '");';
} else {
str.push('arr.push("');
str.push(tpl.slice(index1).replace(/\s+/g, ' '));
str.push('");');
}
}
isTrim ? str += 'return arr.join("");' : str.push('return arr.join("");');
isTrim ? '' : str = str.join('');
return new Function(str).call(data);
}
window.template = template;
}();
</script>
</head> <body>
<div id="app"></div>
<script type="text/html" id="template">
<h1>
<%data.text%>
</h1>
<div>
<%if (!data.arr) {%>
<h3>数据暂时为空哦!</h3>
<div>
<%}else{%>
<ul>
<%for (var i = 0;i < data.arr.length;i++) {%>
<li>
<%for (var j = 0;j < data.arr[i].length;j++) {%>
<a href="javascript:void(0)" data_id="<%data.arr[i][j].id%>">
<%data.arr[i][j].name%>
<span>——</span>
<%data.arr[i][j].value%>
</a><br>
<%}%>
</li>
<%}%>
</ul>
<%}%>
</div>
</script>
<script>
var data = {
text: "简单地template",
arr: [
[{ id: 1000, name: "葛小伦", value: "银河之力" }, { id: 1001, name: "刘闯", value: "长城一号" }, { id: 1002, name: "蕾娜", value: "太阳之光" }, { id: 1003, name: "赵信", value: "人生赢家啊" }],
[{ id: 2000, name: "宋江", value: "及时雨" }, { id: 2001, name: "晁盖", value: "天王" }, { id: 2002, name: "林冲", value: "豹子头" }, { id: 2003, name: "武松", value: "行者" }],
[{ id: 3000, name: "曹操", value: "丞相" }, { id: 3001, name: "关羽", value: "汉寿亭侯" }]
]
};
var html = template(document.getElementById('template').innerHTML, data);
document.getElementById('app').innerHTML = html;
</script>
</body>
</html>

一个简单地template模板的更多相关文章

  1. OpenCms JSP 模板开发——创建一个简单的JSP模板

    OpenCms中的JSP模板就是一个普通的JSP页面,在特定的位置使用标签来包含内容,在这个的例子中,我们将要开发一个简单JSP模板,这个模板只是在内容(如<html>.<body& ...

  2. Html+css 一个简单的网页模板

    一个简单的网页模板,有导航.子菜单.banner部分 1 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN&q ...

  3. 一个简单的PHP模板引擎

    PHP早期开发中通常是PHP代码和HTML代码混写,这也使代码中充斥着数据库操作,逻辑处理等.当项目不大时,这样的代码还可以接受,但是随着项目不断扩大,我们就会发现同一个文件中同时存在前端逻辑和后端处 ...

  4. 一个简单的模板引(han)擎(shu)

    自制一个简单的模板引(han)擎(shu) 原理 说大了 实际上是模板函数 原理呢就是简单的字符串替换 第一版 var data = { username: 'Muhha' } str = '< ...

  5. web 框架的本质及自定义web框架 模板渲染jinja2 mvc 和 mtv框架 Django框架的下载安装 基于Django实现的一个简单示例

    Django基础一之web框架的本质 本节目录 一 web框架的本质及自定义web框架 二 模板渲染JinJa2 三 MVC和MTV框架 四 Django的下载安装 五 基于Django实现的一个简单 ...

  6. 一个简单的代码生成器(T4文本模板运用)

    说要写这篇文章有一段时间了,但因为最近各方面的压力导致心情十二分的不好,下班后往往都洗洗睡了.今天痛定思痛,终于把这件拖了很久的事做了.好,不废话了,现在看看"一个简单的代码生成器" ...

  7. c++ template 实现一个简单的"栈"

    一: 实现一个简单的swap 原来我们写swap一定会这样写: 对于int类型的: swap(const int &x,const int &y) { int temp; temp = ...

  8. 动手写一个简单的Web框架(模板渲染)

    动手写一个简单的Web框架(模板渲染) 在百度上搜索jinja2,显示的大部分内容都是jinja2的渲染语法,这个不是Web框架需要做的事,最终,居然在Werkzeug的官方文档里找到模板渲染的代码. ...

  9. java课堂测试—根据模板完成一个简单的技术需求征集系统

    课堂上老师发布了一个页面模板要求让我们实现一个系统的功能,模仿以后后端的简单工作情况. 然后在这个模板的基础上,提供了一个注册的网页模板,接着点击注册的按钮,发现register里面调用了zhu/zh ...

随机推荐

  1. 初识git(17/8/21)

    git是一个分布式的版本管理系统 通过廖雪峰的官方网站(maybe2017)来学习的,比较详实跟着操作就行,记录基本的一些命令还有学习是遇到的一些问题和收获,方便下次查阅. git的安装 -. win ...

  2. 第十二章 Java内存模型与线程

    Java内存模型(Java Memory Model,JMM): 主内存与工作内存:Java内存模型主要是定义程序中各个变量的访问规则.Java内存模型规定了所有的变量都存储在主内存(Main Mem ...

  3. layer.open参数;layer.open关闭事件;layer.open关闭刷新;layer.open获取子页的值;layer.open调用子页面的方法

    父页面 function layerOpen() { layer.open({ type: 2, shade: [0], title: "验收申请", area: ['1024px ...

  4. MPI 集合通信函数 MPI_Reduce(),MPI_Allreduce(),MPI_Bcast(),MPI_Scatter(),MPI_Gather(),MPI_Allgather(),MPI_Scan(),MPI_Reduce_Scatter()

    ▶ 八个常用的集合通信函数 ▶ 规约函数 MPI_Reduce(),将通信子内各进程的同一个变量参与规约计算,并向指定的进程输出计算结果 ● 函数原型 MPI_METHOD MPI_Reduce( _ ...

  5. gflags 学习

    一.下载 https://github.com/gflags/gflags 二.可以将gflags编译成lib 三.在需要的工程的workspace下面引入编译好的gflags动态库,在库里面写好BU ...

  6. QPixmap 在非QtCreator环境下无法显示jpg图片

    这几天需要实现在Qt界面中显示jpg图片,于是直接将路径传给QPixmap对象,发现显示不出来. 然而在Qt SDK自带的Demo中却可以正确显示jpg图片,经搜索引擎查找发现,是自己的exe文件缺少 ...

  7. 05 JS基础DOM

    JS的window对象定时器: window下一些方法: <script> 弹出 window.alert('hello') 返回布尔值 var ret = window.confirm( ...

  8. java和.net连接数据库的方法

    .net连接数据库的方法 App.config <connectionStrings> <add name="" connectionString="D ...

  9. winreg操作windows注册表详解示例

    #coding:utf-8 #=====================================================================#=====本程序演示了WINR ...

  10. 分布式之redis核心知识盘点?

    考虑到绝大部分写业务的程序员,在实际开发中使用redis的时候,只会setvalue和getvalue两个操作,对redis整体缺乏一个认知.又恰逢博主某个同事下周要去培训redis,所以博主斗胆以r ...