javascript 模板系统 ejs v7
javascript模板系统 ejs 第七版!
本版本只要是对其易用性进一些修改,去掉两个冗余的功能。
我发现我的模块系统天生就能实现模块套嵌,因此有关子模板导入的两个操作符去掉。
对参数进行多态化,可简单地传入一个字符串来指定目标元素的选择器或目标文件的URL(通过url(http://)来区分)与一个参数对象,也可以像EXT那样传入一个哈希。
//dom.ejs v7 by 司徒正美
//http://www.cnblogs.com/rubylouvre/archive/2010/10/04/1841933.html
;
(function(){
this.dom = {
quote : String.quote || function (str) {
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, '\\"') + '"';
},
mix : function(target, source ,override) {
var i, ride = (override === void 0) || override;
for (i in source) {
if (ride || !(i in target)) {
target[i] = source[i];
}
}
return target;
}
}
if(!String.prototype.trim){
String.prototype.trim = function(){
return this.replace(/^[\s\xa0]+|[\s\xa0]+$/g, '');
}
}
;
(function(w,s){
//http://blogs.msdn.com/xmlteam/archive/2006/10/23/using-the-right-version-of-msxml-in-internet-explorer.aspx
s = ["XMLHttpRequest",
"ActiveXObject('Msxml2.XMLHTTP.6.0')",
"ActiveXObject('Msxml2.XMLHTTP.3.0')",
"ActiveXObject('Msxml2.XMLHTTP')",
"ActiveXObject('Microsoft.XMLHTTP')"];
//IE专有的JScript方法:ScriptEngine,ScriptEngineBuildVersion,ScriptEngineMajorVersion,ScriptEngineMinorVersion,CollectGarbage,RuntimeObject和GetObject。
if( !-[1,] && w.ScriptEngineMinorVersion() === 7 && location.protocol === "file:"){
s.shift();
}
for(var i = 0 ,el;el=s[i++];){
try{
if(eval("new "+el)){
dom.xhr = new Function( "return new "+el);
break;
}
}catch(e){}
}
})(window);
var
metaObject = {
'\b': '\\b',
'\t': '\\t',
'\n': '\\n',
'\f': '\\f',
'\r': '\\r',
'\\': '\\\\'
},
_startOfHTML = "\t__views.push(",
_endOfHTML = ");\n",
_rAt = /(^|[^\w\u00c0-\uFFFF_])(@)(?=\w)/g,
_partial = function(url){
var xhr = dom.xhr();
xhr.open("GET",url,false);
xhr.setRequestHeader("If-Modified-Since","0");
xhr.send(null);
return xhr.responseText|| ""
},
defaults = {
left: "<&",
right: "&>"
}
var ejs = dom.ejs = function(obj,data){
if(typeof obj === "string"){
if(obj.indexOf("url(") === 0){
obj = {
url : obj.slice(4,-1),
data: data
}
}else{
obj = {
selector:obj,
data :data
}
}
}
dom.mix(obj, defaults,false);
if(!obj.rLeft){
obj.rLeft = new RegExp("\\s*"+obj.left+"\\s*")
obj.rRight = new RegExp("\\s*"+ obj.right+"\\s*");
}
var key = obj.selector || obj.url;
if(!ejs[key]){
var rAt = _rAt, startOfHTML = _startOfHTML, endOfHTML = _endOfHTML,partial = _partial,
buff = ["var __views = [];\n"],str , logic;
if(obj.selector){
var el = document.getElementById(key);
if (!el) throw "can not find the target element";
str = el.text;
}else {
str = partial(obj.url);
if (!str) throw "the target file does not exist";
}
var arr = str.trim().split(obj.rLeft),temp = [],i = 0,n = arr.length,els,segment;
while(i < n){
segment = arr[i++];
els = segment.split(obj.rRight);
if(segment.indexOf(obj.right) !== -1){//这里不使用el.length === 2是为了避开IE的split bug
switch (els[0].charAt(0)) {
case "="://处理后台返回的变量(输出到页面的);
logic = els[0].substring(1);
if(logic.indexOf("@")!==-1){
temp.push(startOfHTML, logic.replace(rAt,"$1data."), endOfHTML);
}else{
temp.push(startOfHTML, logic, endOfHTML);
}
break;
case "#"://处理注释
break;
default://处理逻辑
logic = els[0];
if(logic.indexOf("@")!==-1){
temp.push(logic.replace(rAt,"$1data."), "\n");
}else{
temp.push(logic, "\n");
}
}
//处理静态HTML片断
els[1] && temp.push(startOfHTML, dom.quote.call(null,els[1]), endOfHTML)
}else{
//处理静态HTML片断
temp.push(startOfHTML, dom.quote.call(null,els[0]), endOfHTML)
}
}
ejs[key] = new Function("data",buff.concat(temp).join("")+';return __views.join("");');
}
return ejs[key](obj.data || {});
}
})();
使用方法见如下例子:
更新日志
v1 默认界定符为<% %>,当然也可以自定义界定符,只支持当前页面的script元素做模板 http://www.cnblogs.com/rubylouvre/archive/2010/08/10/1796383.html v2 改进算法提速,比John Resig的 Micro-Templating模板更能应对复杂的模板 http://www.cnblogs.com/rubylouvre/archive/2010/08/22/1805914.html v3 http://www.cnblogs.com/rubylouvre/archive/2010/08/25/1807789.html 增添了局部模板功能 v4 http://www.cnblogs.com/rubylouvre/archive/2010/08/31/1813122.html 对v3的结构进行优化,支持远程的独立文件做模板 v5 http://www.cnblogs.com/rubylouvre/archive/2010/08/31/1813122.html 尝试新的算法 v6 http://www.cnblogs.com/rubylouvre/archive/2010/10/05/1841933.html 更新默认界定符为<& &>,添加新的操作符<&~,对数据源的第一层属性名添加@前缀 v7 对参数进行多态化,因ejs天生支持模板的相互调用便去除<&:与<&~操作符
参数多态化,四种传参方式
//方式1
dom.ejs("id",{aa:"aaa",bb:"bbb"})
//方式2
dom.ejs("url(http://aaa/tmpl.html)",{aa:"aaa",bb:"bbb"})
//方式3
dom.ejs({
selector:"id",
data : {aa:"aaa",bb:"bbb"}
});
//方式4
dom.ejs({
url:"http://aaa/tmpl.html",
data : {aa:"aaa",bb:"bbb"}
})
机器瞎学/数据掩埋/模式混淆/人工智障/深度遗忘/神经掉线/计算机幻觉/专注单身二十五年
浙公网安备 33010602011771号