由于各种原因,被逼使用前台模板。看了一下其他JS模板库的实现,发现其原理并不难,遂决定重造轮子。使用ROR.erb风格。换言之,逻辑是写在"<%"与"%>"之间,如果是注释,则用"<%#"与"%>",凡是后台传过来的变量都加上@来标记。现在这个模板系统还没有搭载任何helper方法,也不依赖任何代码,因此非常精短。
| <meta content="IE=8" http-equiv="X-UA-Compatible"/> |
| <meta name="keywords" content="javascript模板 by 司徒正美" /> |
| <meta name="description" content="javascript模板 by 司徒正美" /> |
| <title>javascript模板 by 司徒正美title> |
| <h1>javascript模板 by 司徒正美h1> |
| <textarea id="tmpl" style="display:none;" > |
| <% for(var i=0; i<@supplies.length; i++) {%> |
| <li><%= @supplies[i] %>li> |
| <p style="text-indent:2em;"><%=@address %>p> |
| window.onload = function(){ |
| dom.erb("tmpl", {name:"司徒正美",supplies:["第一个LI元素","第二个LI元素","第三个LI元素","第四个LI元素"],address:"异次元"}) |
模板系统:
| str = str.replace(/[\x00-\x1f\\]/g, function (chr) { |
| var special = metaObject[chr]; |
| return special ? special : '\\u' + ('0000' + chr.charCodeAt(0).toString(16)).slice(-4) |
| return '"' + str.replace(/"/g, '\\"') + '"'; |
| //selector ,必须,String, 模板容器textarea的ID值 |
| //onsite,可选,Boolean,是否就地替换掉模板容器,默认true,如果为false,则返回一个文档碎片,交由用户自己插入到需要的地方 |
| dom.erb = function (selector, json, onsite) { |
| onsite = !!onsite|| true; |
| var el = document.getElementById(selector); |
| if (!el) throw "找不到目标元素"; |
| var arr = text.split(/\s*<%\s*|\s*%>\s*/g), |
| buff = ["var __views = [];\n"] |
| for (var i = 0, segment, n = arr.length; i < n; i++) { |
| if (i & 1) { //偶数项,处理动态的逻辑 |
| switch (segment.charAt(0)) { |
| buff.push(erb.startOfHTML, dom.quote("<!--" + segment + "-->"), erb.endOfHTML); |
| if (segment.indexOf("@") !== -1) { //处理后台返回的变量(输出到页面的) |
| buff.push(erb.startOfHTML, segment.slice(1).replace(erb.rAt, "$1json."), erb.endOfHTML); |
| buff.push(erb.startOfHTML, segment.slice(1), erb.endOfHTML) |
| if (segment.indexOf("@") !== -1) { //处理后台返回的变量 |
| buff.push(segment.replace(erb.rAt, "$1json."), "\n"); |
| } else { //奇数项,处理静态的HTML片断 |
| buff.push(erb.startOfHTML, dom.quote(segment), erb.endOfHTML); |
| erb[selector] = new Function("json", buff.join("") + ';return __views.join("");') |
| div.innerHTML = erb[selector](json); |
| var fragment = document.createDocumentFragment(); |
| fragment.appendChild(div.firstChild) |
| return onsite ? el.parentNode.replaceChild(fragment, el) : fragment; |
| dom.erb.parser = document.createElement("div"); |
| dom.erb.startOfHTML = "\t__views.push("; |
| dom.erb.endOfHTML = ");\n"; |
| dom.erb.rAt = /(^|[^\w\u00c0-\uFFFF_])(@)(?=\w)/g; |
javascript模板 by 司徒正美
javascript模板 by 司徒正美
运行代码
PS:发现javascript模板没有想象中的糟糕,尤其是大流量的页面在无法使用UI库的情况下,这是个不错的选择,例子如qq zone与ニコニコ動画。
来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/12639172/viewspace-670847/
,如需转载,请注明出处,否则将追究法律责任。