JavaScript输入邮箱自动提示实例代码
JavaScript输入邮箱自动提示实例代码
发布时间:2016-12-30 来源:查字典编辑
摘要:本来想把之前对artTemplate源码解析的注释放上来分享下,不过隔了一年,找不到了,只好把当时分析模板引擎原理后,自己尝试写下的模板引擎...

本来想把之前对artTemplate源码解析的注释放上来分享下,不过隔了一年,找不到了,只好把当时分析模板引擎原理后,自己尝试

写下的模板引擎与大家分享下,留个纪念,记得当时还对比了好几个模板引擎来着。

这里所说的js的模板引擎,用的是原生的javascript语法,所以很类似php的原生模板引擎。

前端模板引擎的作用?

1. 可以让前端开发更简单,不需要为了生成一个dom结构而使用+运算符去拼接字符串,而只需要一个元素的(里面的html模板),或者一个变量(存储着模板),或者一个模板文件

2. 易于维护,减少耦合,假使你的dom结构变化了,不需要更改逻辑代码,而只需要更改对应的模板(文件)

3. 可以缓存,如果你的模板是一个类似.tpl的文件,那么完全可以用浏览器去加载,并且还存下来。说到.tpl文件,可以做的不仅仅是缓存了,你还可以做到通过模块加载器

将.tpl作为一个模块,那就可以按需加载文件,不是更省宽带,加快页面速度吗?

4. 等等等

前端模板引擎的原理?

原理很简单就是 对象(数据)+ 模板(含有变量) -> 字符串(html)

前端模板引擎的如何实现?

通过解析模板,根据词法,将模板转换成一个函数,然后通过调用该函数,并传递对象(数据),输出字符串(html)

(当然,具体的还要看代码的)

就像这样:

复制代码 代码如下:

var tpl = 'i am <%= name%>, <%= age=> years old'; // <%=xxx>% 词法,标记为变量

var obj = {

name : 'lovesueee' ,

age : 24

};

var fn = Engine.compile(tpl); // 编译成函数

var str = fn(obj); // 渲染出字符串

例子:

复制代码 代码如下:

<!DOCTYPE HTML>

<html>

<head>

<meta http-equiv="Content-Type" content="text/html; charset=utf-8">

<title>ice demo</title>

<script src="http://www.jb51.netjavascripts/jquery/jquery-1.7.2.js"></script>

<script src="http://www.jb51.netjavascripts/ice/ice.js"></script>

<body>

<div id="content"></div>

</body>

<script type="text/html" id="tpl">

<div>here is the render result:</div>

<% = this.title() ;%>

<table border=1>

<% for(var i=0,tl = this.trs.length,tr;i<tl;i++){ %>

<%

tr = this.trs[i];

if (tr.sex === "女") {

%>

<tr>

<td><%= tr.name;; %></td> <td><%= tr.age; %></td> <td><%= tr.sex || "男" %></td>

</tr>

<% } %>

<% } %>

</table>

<img src="<%= this.href %>">

<%= this.include('tpl2',this); %>

</script>

<script type="text/html" id="tpl2">

<div>here is the render result:</div>

<% = this.print('Welcome to Ice Template') ;%>

<table border=1>

<% for(var i=0,tl = this.trs.length,tr;i<tl;i++){ %>

<%

tr = this.trs[i];

if (tr.sex === "男") {

%>

<tr>

<td><%= tr.name;; %></td> <td><%= tr.age; %></td> <td><%= tr.sex || "男" %></td>

</tr>

<% } %>

<% } %>

</table>

<img src="<%= this.href %>">

</script>

<script>

var trs = [

{name:"隐形杀手",age:29,sex:"男"},

{name:"索拉",age:22,sex:"男"},

{name:"fesyo",age:23,sex:"女"},

{name:"恋妖壶",age:18,sex:"男"},

{name:"竜崎",age:25,sex:"男"},

{name:"你不懂的",age:30,sex:"女"}

]

// var html = ice("tpl",{

// trs: trs,

// href: "http://images.jb51.net/type4.jpg"

// },{

// title: function(){

// return "<p>这是使用视图helper输出的代码片断</p>"

// }

// });

var elem = document.getElementById('tpl');

var tpl = elem.innerHTML;

var html = ice(tpl,{

trs: trs,

href: "http://images.jb51.net/type4.jpg"

},{

title: function(){

return "<p>这是使用视图helper输出的代码片断</p>"

}

});

console.log(html);

$("#content").html(html);

</script>

</html>

简单的实现:

复制代码 代码如下:

(function (win) {

// 模板引擎路由函数

var ice = function (id, content) {

return ice[

typeof content === 'object' ? 'render' : 'compile'

].apply(ice, arguments);

};

ice.version = '1.0.0';

// 模板配置

var iConfig = {

openTag : '<%',

closeTag : '%>'

};

var isNewEngine = !!String.prototype.trim;

// 模板缓存

var iCache = ice.cache = {};

// 辅助函数

var iHelper = {

include : function (id, data) {

return iRender(id, data);

},

print : function (str) {

return str;

}

};

// 原型继承

var iExtend = Object.create || function (object) {

function Fn () {};

Fn.prototype = object;

return new Fn;

};

// 模板编译

var iCompile = ice.compile = function (id, tpl, options) {

var cache = null;

id && (cache = iCache[id]);

if (cache) {

return cache;

}

// [id | tpl]

if (typeof tpl !== 'string') {

var elem = document.getElementById(id);

options = tpl;

if (elem) {

// [id, options]

options = tpl;

tpl = elem.value || elem.innerHTML;

} else {

//[tpl, options]

tpl = id;

id = null;

}

}

options = options || {};

var render = iParse(tpl, options);

id && (iCache[id] = render);

return render;

};

// 模板渲染

var iRender = ice.render = function (id, data, options) {

return iCompile(id, options)(data);

};

var iForEach = Array.prototype.forEach ?

function(arr, fn) {

arr.forEach(fn)

} :

function(arr, fn) {

for (var i = 0; i < arr.length; i++) {

fn(arr[i], i, arr)

}

};

// 模板解析

var iParse = function (tpl, options) {

var html = [];

var js = [];

var openTag = options.openTag || iConfig['openTag'];

var closeTag = options.closeTag || iConfig['closeTag'];

// 根据浏览器采取不同的拼接字符串策略

var replaces = isNewEngine

?["var out='',line=1;", "out+=", ";", "out+=html[", "];", "this.result=out;"]

: ["var out=[],line=1;", "out.push(", ");", "out.push(html[", "]);", "this.result=out.join('');"];

// 函数体

var body = replaces[0];

iForEach(tpl.split(openTag), function(val, i) {

if (!val) {

return;

}

var parts = val.split(closeTag);

var head = parts[0];

var foot = parts[1];

var len = parts.length;

// html

if (len === 1) {

body += replaces[3] + html.length + replaces[4];

html.push(head);

} else {

if (head ) {

// code

// 去除空格

head = head

.replace(/^s+|s+$/g, '')

.replace(/[nr]+s*/, '')

// 输出语句

if (head.indexOf('=') === 0) {

head = head.substring(1).replace(/^[s]+|[s;]+$/g, '');

body += replaces[1] + head + replaces[2];

} else {

body += head;

}

body += 'line+=1;';

js.push(head);

}

// html

if (foot) {

_foot = foot.replace(/^[nr]+s*/g, '');

if (!_foot) {

return;

}

body += replaces[3] + html.length + replaces[4];

html.push(foot);

}

}

});

body = "var Render=function(data){ice.mix(this, data);try{"

+ body

+ replaces[5]

+ "}catch(e){ice.log('rend error : ', line, 'line');ice.log('invalid statement : ', js[line-1]);throw e;}};"

+ "var proto=Render.prototype=iExtend(iHelper);"

+ "ice.mix(proto, options);"

+ "return function(data){return new Render(data).result;};";

var render = new Function('html', 'js', 'iExtend', 'iHelper', 'options', body);

return render(html, js, iExtend, iHelper, options);

};

ice.log = function () {

if (typeof console === 'undefined') {

return;

}

var args = Array.prototype.slice.call(arguments);

console.log.apply && console.log.apply(console, args);

};

// 合并对象

ice.mix = function (target, source) {

for (var key in source) {

if (source.hasOwnProperty(key)) {

target[key] = source[key];

}

}

};

// 注册函数

ice.on = function (name, fn) {

iHelper[name] = fn;

};

// 清除缓存

ice.clearCache = function () {

iCache = {};

};

// 更改配置

ice.set = function (name, value) {

iConfig[name] = value;

};

// 暴露接口

if (typeof module !== 'undefined' && module.exports) {

module.exports = template;

} else {

win.ice = ice;

}

})(window);

推荐文章
猜你喜欢
附近的人在看
推荐阅读
拓展阅读
相关阅读
网友关注
最新Javascript教程学习
热门Javascript教程学习
编程开发子分类