中级JavaScript例子, 如何实现一个简单实用的模板套用机制, GXTemplate , 第2章(估计要写9章)

接 第1章 http://blog.csdn.net/zhgangxuan/article/details/50610883 


第2章 下载地址  https://github.com/zhgangxuan/GXTemplate/blob/master/_oldfiles/version1/template02.html 
源代码 

<!DOCTYPE html>
<html>
<head>
	<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
	<title>text node</title>

	<script src="data.js"></script>
	<style>
		.templatedevelopmodetextnode {
			color: firebrick;
			text-decoration: underline;
		}
	</style>
</head>

<body>

	<h1>{#myitem.name}</h1>
	<p>
		Address: {#myitem.address}
		-
		Zip: {#myitem.zipcode}
		-
		Phone: {#myitem.phone}
	</p>

</body>


<script>

	var re_template_textbinding = /{#([^}]+)}/g;

	function ProcessEval($__exp__) {
		return eval($__exp__);
	}

	function ProcessTextNode(node, str) {
		var arr;
		var pos = 0;
		str.replace(re_template_textbinding, function (exp, g1, index, full) {
			if (!arr) arr = [];
			if (pos < index)
				arr.push(str.substring(pos, index));
			pos = index + exp.length;

			var span = document.createElement("span");
			span.className = "templatedevelopmodetextnode";
			span.title = exp;
			span.innerText = ProcessEval(g1);
			arr.push(span);
		});
		if (!arr)
			return;

		if (pos < str.length)
			arr.push(str.substring(pos));

		var p = node.parentNode;
		for (var i = 0; i < arr.length; i++) {
			var childnode = arr[i];
			if (typeof (childnode) == "string") {
				childnode = document.createTextNode(childnode);
			}
			p.insertBefore(childnode, node);
		}
		p.removeChild(node);
	}

	function TemplateExecute(node) {

		if (node.nodeType == 3) {
			var str = node.nodeValue;
			if (str.indexOf('{#') != -1)
				ProcessTextNode(node, str);
			return;
		}

		if (node.nodeType != 1)
			return;
		switch (node.nodeName) {
			case "SCRIPT":
			case "STYLE":
				return;
		}

		var cns = node.childNodes;
		for (var ni = cns.length; ni > 0; ni--)
			TemplateExecute(cns.item(cns.length - ni));

	}


	TemplateExecute(document.body);


</script>


</html>

目标:

让文本绑定后能分片处理, 把{#脚本返回值}作为span插进DOM中


实现过程:

这个例子与第1章不同的地方主要是ProcessTextNode的处理方法.

第一章只是简单的作如下处理:

	function ProcessTextNode(node, str) {
		var newstr = str.replace(re_template_textbinding, function (exp, g1, index, full) {
			return ProcessEval(g1);
		});
		if (newstr != str) node.nodeValue = newstr;
	}

第2章则使用str.replace(re_template_textbinding)的方式, 纯粹收集正则表达式所能搜索到的所有片段. 

		str.replace(re_template_textbinding, function (exp, g1, index, full) {
			if (!arr) arr = [];
			if (pos < index)
				arr.push(str.substring(pos, index));
			pos = index + exp.length;

			var span = document.createElement("span");
			span.className = "templatedevelopmodetextnode";
			span.title = exp;
			span.innerText = ProcessEval(g1);
			arr.push(span);
		});

由于每个符合正则表达式的前后, 都有可能存在普通的文本, 所以使用了pos变量记录了普通文本的开始位置. 并且适当地substring加到arr中. 


如果实在收集不到任何符合正则表达式的, 那么就忽略当前节点. 否则把最后的普通文本加入到arr中.

		if (!arr)
			return;
		if (pos < str.length)
			arr.push(str.substring(pos));

收集符合正则表达式是本章的重点了. 而后面逐一处理数组的每一项则是很普通 : 把字符串转换成textnode, 和span一起, 逐项放到node的前面. 最后把原来的node删除掉.

		var p = node.parentNode;
		for (var i = 0; i < arr.length; i++) {
			var childnode = arr[i];
			if (typeof (childnode) == "string") {
				childnode = document.createTextNode(childnode);
			}
			p.insertBefore(childnode, node);
		}
		p.removeChild(node);

实际上整个GXTemplate的v1.0版都已经上传到github的了.  接下来我们的业余时间主要是谢谢例子, 写写教程. 
对于不懂得使用github的朋友, 可以直接下载源代码 https://github.com/zhgangxuan/GXTemplate/archive/master.zip




  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值