[自制模板引擎]添加指令
模板引擎最大的一个特点就是其指令系统,通过执行一些简单的表达式,可以让这个模板引擎拥有计算功能,但是拥有指令,能让模板引擎拥有更强大的功能,下面来试着实现一些简单的指令,如for,if等等
扩展前面的一段遍历节点的代码,我需要在遍历节点的时候把这些内置的指令做特殊的处理,假设指令是向这样存在的 <div cc-for="arr"></div> :
function eachNode(ele,obj) { //看看自身属性是否有需要转换属性 var attrs = ele.attributes; var childNodes = ele.childNodes; forEach(attrs,function(attr,index){ if (perFix.exec(attr.nodeName)) { //存在转换的属性,是否需要求值 setTimeout(function(){ //把属性处理器提出执行列队 //避免在执行过程中污染原来的dom结构 attrHandle(attr.nodeName.substr(3),ele,attr.value); },0) } }); if (ele.getAttribute("cc-each")) { return; } return ele; }
不管以怎样的形式存在,重要的是找到它们然后对它们作出响应的处理,所以创建一个处理它们的函数。
function attrHandle(type,node,value){ var newObj = buildExpression(value,originObj); switch (type) { case "each" : //创建一个文档碎片 var fragment = document.createDocumentFragment(); var i = 0; var l; var newNode; node.removeAttribute("cc-each"); //判断是数组还是对象 if (Object.prototype.toString.call(newObj) === "[object Array]"){ for (l = newObj.length;i<l;i++) { newNode = node.cloneNode(true); fragment.appendChild(eachNode(newNode,newObj[i])); } node.parentNode.replaceChild(fragment,node); }else{ for (var k in newObj) { newNode = node.cloneNode(true); fragment.appendChild(eachNode(newNode,newObj[k])); } node.parentNode.replaceChild(fragment,node); } break; case "click" : node.addEventListener("click",newObj,false); break; case "if" : if (newObj) { node.style.display = "block"; }else{ node.style.display = "none"; } break; } }
最后送上github地址:git@github.com:taixw2/temptale.git
本系列就草草结束,我发现比写代码更累的是管理好博客。