JS实现简单的template

这篇文章,感觉就是在凑数的,本不想写的,因为并没有什么我觉得要说的知识点存在,但依然写了这篇,只是因为想说一种思想,懒人思想?我是这么认为的。

写在前面

这里我本想写出一些很深刻的话,很煽情的句子,只是语言表达能力确实有限,还是一切从简吧。

懒人思想,顾名思义,就是懒人的想法呗,虽然大家都会觉得人懒不会好,但懒人却在改变着这个世界(说的貌似有点大),举几个例子呗:今天太热,不想出去吃饭了,怎么办?有外卖…;到夏天了,没有夏天的衣服换,又不想去买,有网购和物流。举例子太难想了,总结一句话,懒人的需求,就是在推动这个时代的进步(感觉确实说大了,汗。。。)。所以呢,我觉得吧,懒人思想可以认为是,为了满足懒人的需求,而出现的一些想法或者设想。想想,什么东西的出现,会让人可以变得更懒?想到并且做到做好,您就更改变这个世界。

说的跑题了,也算没有跑题,因为在程序员的世界里,功能模块的重复利用,就会让程序员们变得更懒,而一些框架的存在,也让程序员们变得更懒。比如,在工作中(就说前端吧),使用jQuery也许只要几行代码就可以实现的功能,而原生的JS却需要几十行或者上百行才能完成,而且还要担心不同浏览器的兼容问题,这个时候一般会怎么选择呢?当然啦,学习还是要更多的学习基础才是王道,使用框架毕竟还是在依靠其他外力。

说到这里,感觉说的这么大这个那啥的,好像这些外力说白了也就是我们常说的框架或者插件。。。。

最简单的html解析引擎

也就是我们常说的模板吧,就像我们常见的后端语言中,都有使用一些模板来实现动态页面,这里只想说一个前端的页面html引擎。在文章最初说不想写这篇文章,也是因为有看到过别人写的一个更好更牛更nice的引擎:中文地址翻译英文原文地址

所以,这里只就自己的需求,写一个最简单的方法了。

不说了,说多了也是废话,想必很多人都有想到过这个方法的。该方法的基本思想,主要是基于字符串方法中的replace方法和正则表达式,如果您对该方法并不熟悉,可以参考我之前的两篇文章,字符串的replace方法基础简介强大的replace方法,而正则表达式的文章却一直没有写,因为自己有看到过一篇很不错的正则表达式,而自己又没有对正则有更多的新的认识,如果您对正则还不太了解,可以参考:正则表达式30分钟入门教程

代码就很简单了,直接看例子吧。


var html = '<p>Hello, my name is <%=name %>. I\'m <%= age %> years old.</p>';



var data = {name:"zhang",age:"222"};

function template(html,data){
    //data是一个对象,即需要填充的数据
    //html是填充好数据之后,返回的html代码,为字符串
    var regGet = /\<\%\=([^\%\>]+)?\%\>/g,
	//获取目标的字符串
	regTrim = /^\s+|\s+$/g;
	//去掉字符串开头和结尾的空格符
    return html.replace(regGet,function($1,$2){
	return data[$2.replace(regTrim,"")];
    });
}
var html = template(html,data);
document.write(html);


最简单的实例了,好像貌似,上面的代码怎么执行的,也没有什么好说的。

但是这里有一个问题就是,如果我把html的格式写成下面的这样:


var html = '<p>Hello, my name is <%=name.first%>. I\'m <%=age%> years old.</p>';


再使用上面的方法的话,就会出现这样的结果了:


Hello, my name is undefined. I'm 222 years old.


这并不是我们想要的,所以这里就需要对这个方法进行下一步的处理:当出现上面的<%=name.first%>写法时,就需要对获取到的字符串(即上面的代码中的$2继续处理,获取到对应的属性值了),比如可以添加一个新的判断,比如像下面这样:


var html = '<p>Hello, my name is <%= name.first %>. I\'m <%= age %> years old.</p>';



var data = {name:{first:"zhangyun"},age:"222"};

function template(html,data){
    //data是一个对象,即需要填充的数据
    //html是填充好数据之后,返回的html代码,为字符串
    var regGet = /\<\%\=([^\%\>]+)?\%\>/g,
	//获取目标的字符串
	regTrim = /^\s+|\s+$/g,
	//去掉字符串开头和结尾的空格符
	regReplace = /(?:^|\.)([^\.]+)?/g;
	//按点操作符,继续处理

    return html.replace(regGet,function($1,$2){
  	var result = "";
	
        $2.replace(regTrim,"").replace(regReplace,function(p1,p2){
	    result = result == ""?data[p2]:result[p2]?result[p2]:result;
	});
	return result;
    });
}
var html = template(html,data);
document.write(html);


这样就可以处理一些我们常见的结构了吧,不过如果是需要循环的那种呢,有些引擎是可以直接在js中支持js语句循环的,这里呢,我们支持把循环写在js内部,循环引用该函数,并把返回的字符串进行连接即可。

比如,我想要生成多个上面同样结构的字符串,那么就可以直接使用data循环属性了。


var data = [{name:{first:"zhang"},age:"1"},{name:{first:"yun"},age:"2"},{name:{first:"ling"},age:"3"}];
var res = "";
for(var i=0,len=data.length;i<len;i++){
	res += template(html,data[i]);
}
document.write(res);


上述代码中,没有包含的内容就是和上面的其他代码相同,所以就没有在这里继续添加。

OK,这样也就差不多了,这只是一个想法,代码中可能也有很多进行优化的部分,也有其他的方法实现的,只是这里是按照我个人的喜好,实现的一段代码。同时之所以使用replace方法,也是出于个人喜好。在template内部进行子元素查询的时候,也可以使用split方法转换成数组,然后使用循环进行处理。各种其他的方法,我们都可以尝试的,这里就不做说明了。

至于这个方法的必要性,也就个人有各人的评论了。

本文地址:http://www.zhangyunling.com/?p=168

发表评论

电子邮件地址不会被公开。 必填项已用*标注

您可以使用这些HTML标签和属性: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>