JAvascriptテンプレートシステムejs v 3
13387 ワード
このバージョンでは、ローカルテンプレート機能が追加され、プライマリテンプレートがローカルテンプレートを呼び出し、ローカルモジュールがローカルモジュールを呼び出し、onsite変数を削除し、ユーザーに解析されたドキュメントの破片を提供しなくなりました.同期要求によって得られたテキストをキャッシュした配列と,全体的な解析が完了したテンプレート関数の二重キャッシュを用いる.テンプレート関数は配列要素を組み合わせて解析したものであり,これは効率を大幅に向上させた.しかし新機能の追加により,新たな構築アルゴリズムを動員してもv 2の構築速度には及ばないが…
定義記号に<%と%>を使用しないでくださいという人もいますが、この問題はv 1バージョンですでに提出しましたが、これらはカスタマイズできます.この例ではDjangoの{と}}スタイルの使い方を示します.
最後に、このバージョンの新しい機能を盛大に紹介します.ただし、条件が限られているため、プレゼンテーションはできません.テンプレートは、ページのscriptラベルに埋め込まれているだけでなく、html、ejs、textなどの独立したファイルに配置することもできます.このファイルは、テンプレート関数を構築するために同期要求で返されます.urlプロパティを使用するか、テンプレートで<%:/template/partailを使用できます.ejs>実装.一般にurlはプライマリテンプレートに使用され、<%:url%>はローカルテンプレートに使用されます.構成オブジェクトでselectorとurlを同時に使用する場合、selectorの優先度はurlより高いです.
ソース:
例:
javascriptテンプレートby司徒正美
javascriptテンプレートby司徒正美
これは注釈です!!!!!!!!!!!!!}}
{{ var color = "color:red;"}}
(function () {
if(!String.prototype.trim){
String.prototype.trim = function(str){
return this.replace(/^[\s\xa0]+|[\s\xa0]+$/g, '');
}
}
var dom = {
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, '\\"') + '"';
}
},
metaObject = {
'\b': '\\b',
'\t': '\\t',
'
': '\
',
'\f': '\\f',
'\r': '\\r',
'\\': '\\\\'
},
startOfHTML = "\t__views.push(",
endOfHTML = ");
";
(function(){
//http://blogs.msdn.com/xmlteam/archive/2006/10/23/using-the-right-version-of-msxml-in-internet-explorer.aspx
var s = ["XMLHttpRequest",
"ActiveXObject('Msxml2.XMLHTTP.6.0')",
"ActiveXObject('Msxml2.XMLHTTP.3.0')",
"ActiveXObject('Msxml2.XMLHTTP')",
"ActiveXObject('Microsoft.XMLHTTP')"];
if( eval("''+/*@cc_on"+"@_jscript_version@*/-0")*1 === 5.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){}
}
})();
dom.partial = function(url){
var xhr = dom.xhr();
xhr.open("GET",url,false);
xhr.setRequestHeader("If-Modified-Since","0");
xhr.send(null);
return xhr.responseText|| ""
}
dom.tmpl = function(str,rLeft,rRight,sRight){
var arr = str.trim().split(rLeft),self = arguments.callee,buff = [],url,els,el,i = 0, n= arr.length;
while (iels = arr[i++]; el = els.split(rRight);
if(els.indexOf(sRight) !== -1){//ここでels.length==2を使わないのはIEのsplitバグを避けるためです
switch (el[0].charAt(0)) {
case"#"://コメントの処理
break;
case"="//バックグラウンドで返される変数(ページに出力される)の処理;
buff.push(startOfHTML, el[0].substring(1), endOfHTML)
break;
ケース"://ローカルテンプレートの処理
url = el[0].substring(1).trim();
self[url] = self[url] || self.call(null,dom.partial(url),rLeft,rRight,sRight);
buff = buff.concat(dom.tmpl[url] );
break;
default:
buff.push(el[0], "
");
};
el[1] && buff.push(startOfHTML, dom.quote.call(null,el[1]), endOfHTML);
}else{
buff.push(startOfHTML, dom.quote.call(null,el[0]), endOfHTML);
}
}
return buff;
}
dom.ejs = function (obj) {
var sLeft = obj.left || "%>",
sRight = obj.right || "<%",
rLeft = new RegExp("\\s*"+sLeft+"\\s*"),
rRight = new RegExp("\\s*"+sRight+"\\s*"),
buff = ["var __views = [];
"],
key = obj.selector || obj.url,str;
if(obj.selector){
var el = document.getElementById(key);
if(!el)throw「ターゲット要素が見つからない」;
str = el.text;
}else{
str = dom.partial(key);
if(!str)throw「ターゲットファイルが存在しない」;
}
if(!dom.tmpl[key]){//セレクタ-->解析関数としてdom.tmpl関数にキャッシュ
buff = buff.concat(dom.tmpl.call(null,str,rLeft,rRight,sRight));
dom.tmpl[key] = new Function("json", "with(json){"+buff.join("") + '\t};return __views.join("");');
}
return dom.tmpl[key](obj.json || {});
};
window.dom = dom;
})();
window.onload = function(){
var els = [];
for(var i=0;i<1000;i++){
els.Push(「第」+i+「個の要素」)
}
var a = new Date
var data = dom.ejs({
selector:"tmpl",
left:"{{",
right:"}}",
json: {
name:「司徒正美」,
uls:els,
address:「異次元」
}
});
document.getElementById("tmplTC").innerHTML = data;
alert( new Date-a)
}
実行コード
今私は1つの考慮があって、テンプレートの規模の膨張に従って、中にますます多くの変数が混ざっているかもしれませんが、私たちはそれらのバックグラウンドから伝わったものをはっきり見分けることができません.それらは地元の臨時変数で、バックグラウンドの需要が変更されると、バックグラウンドのjsonデータも変更されます.これは維持が非常に難しい.だから私はrubyの変数の書く風格をとても鑑賞して、変数名からそれが実例の変数であることを知っていて、類の変数、普通の変数と定数、それは記号のこのものがあって、私はv 4バージョンに参加して@識別子を再加入します.
定義記号に<%と%>を使用しないでくださいという人もいますが、この問題はv 1バージョンですでに提出しましたが、これらはカスタマイズできます.この例ではDjangoの{と}}スタイルの使い方を示します.
最後に、このバージョンの新しい機能を盛大に紹介します.ただし、条件が限られているため、プレゼンテーションはできません.テンプレートは、ページのscriptラベルに埋め込まれているだけでなく、html、ejs、textなどの独立したファイルに配置することもできます.このファイルは、テンプレート関数を構築するために同期要求で返されます.urlプロパティを使用するか、テンプレートで<%:/template/partailを使用できます.ejs>実装.一般にurlはプライマリテンプレートに使用され、<%:url%>はローカルテンプレートに使用されます.構成オブジェクトでselectorとurlを同時に使用する場合、selectorの優先度はurlより高いです.
var data = dom.ejs({
selector:"tmpl",
url:"/template/aaa.html",
left:"{{",
right:"}}",
json: {
name:" ",
blog:"ruby louvre"
address:" "
}
});
ソース:
// javascript template - http://www.cnblogs.com/rubylouvre/ - MIT Licensed
(function () {
if(!String.prototype.trim){
String.prototype.trim = function(){
return this.replace(/^[\s\xa0]+|[\s\xa0]+$/g, '');
}
}
var dom = {
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, '\\"') + '"';
}
},
metaObject = {
'\b': '\\b',
'\t': '\\t',
'
': '\
',
'\f': '\\f',
'\r': '\\r',
'\\': '\\\\'
},
startOfHTML = "\t__views.push(",
endOfHTML = ");
";
(function(){
//http://blogs.msdn.com/xmlteam/archive/2006/10/23/using-the-right-version-of-msxml-in-internet-explorer.aspx
var s = ["XMLHttpRequest",
"ActiveXObject('Msxml2.XMLHTTP.6.0')",
"ActiveXObject('Msxml2.XMLHTTP.3.0')",
"ActiveXObject('Msxml2.XMLHTTP')",
"ActiveXObject('Microsoft.XMLHTTP')"];
if( eval("''+/*@cc_on"+" @_jscript_version@*/-0")*1 === 5.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){}
}
})();
dom.partial = function(url){
var xhr = dom.xhr();
xhr.open("GET",url,false);
xhr.setRequestHeader("If-Modified-Since","0");
xhr.send(null);
return xhr.responseText|| ""
}
dom.tmpl = function(str,rLeft,rRight,sRight){
var arr = str.trim().split(rLeft),self = arguments.callee,buff = [],url,els,el,i = 0, n= arr.length;
while (i<n) {
els = arr[i++]; el = els.split(rRight);
if(els.indexOf(sRight) !== -1){// els.length === 2 IE split bug
switch (el[0].charAt(0)) {
case "#"://
break;
case "=":// ( );
buff.push(startOfHTML, el[0].substring(1), endOfHTML)
break;
case ":"://
url = el[0].substring(1).trim();
//
self[url] = self[url] || self.call(null,dom.partial(url),rLeft,rRight,sRight);
buff = buff.concat(dom.tmpl[url] );
break;
default:
buff.push(el[0], "
");
};
el[1] && buff.push(startOfHTML, dom.quote.call(null,el[1]), endOfHTML);
}else{
buff.push(startOfHTML, dom.quote.call(null,el[0]), endOfHTML);
}
}
return buff;
}
dom.ejs = function (obj) {
var sLeft = obj.left || "%>",
sRight = obj.right || "<%",
rLeft = new RegExp("\\s*"+sLeft+"\\s*"),
rRight = new RegExp("\\s*"+sRight+"\\s*"),
buff = ["var __views = [];
"],
key = obj.selector || obj.url,str;
if(obj.selector){
var el = document.getElementById(key);
if (!el) throw " ";
str = el.text;
}else{
str = dom.partial(key);
if(!str) throw " ";
}
if(!dom.tmpl[key]){//
buff = buff.concat(dom.tmpl.call(null,str,rLeft,rRight,sRight));
dom.tmpl[key] = new Function("json", "with(json){"+buff.join("") + '\t};return __views.join("");');
}
return dom.tmpl[key](obj.json || {});
};
window.dom = dom;
})();
例:
<!doctype html>
<html>
<head>
<meta charset="utf-8"/>
<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>
</head>
<body>
<h1>javascript by </h1>
<div id="tmplTC"> </div>
<script id="tmpl" type="tmpl">
<h2>{{= name }}{{= name }}</h2>
{{# !!!!!!!!! }}
<ul>
{{ for(var i=0; i< uls.length; i++){ }}
<li>{{= uls[i] }} {{= name }}</li>
{{ } }}
</ul>
{{ var color = "color:red;" }}
<p style="text-indent:2em;{{= color }} ">{{= address }}</p>
</script>
<script src="dom/ejs.js"></script>
<script>
window.onload = function(){
var els = [];
for(var i=0;i<1000;i++){
els.push(" "+i+" ")
}
var a = new Date
var data = dom.ejs({
selector:"tmpl",
left:"{{",
right:"}}",
json: {
name:" ",
uls:els,
address:" "
}
});
document.getElementById("tmplTC").innerHTML = data;
alert( new Date-a)
}
</script>
</body>
</html>
これはコンテナ
{{= name }}{{= name }}
これは注釈です!!!!!!!!!!!!!}}
- {=uls[i]}}の名前は{{=name} {{ } }}
{{ for(var i=0; i< uls.length; i++){ }}
{{ var color = "color:red;"}}
{{= address }}
(function () {
if(!String.prototype.trim){
String.prototype.trim = function(str){
return this.replace(/^[\s\xa0]+|[\s\xa0]+$/g, '');
}
}
var dom = {
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, '\\"') + '"';
}
},
metaObject = {
'\b': '\\b',
'\t': '\\t',
'
': '\
',
'\f': '\\f',
'\r': '\\r',
'\\': '\\\\'
},
startOfHTML = "\t__views.push(",
endOfHTML = ");
";
(function(){
//http://blogs.msdn.com/xmlteam/archive/2006/10/23/using-the-right-version-of-msxml-in-internet-explorer.aspx
var s = ["XMLHttpRequest",
"ActiveXObject('Msxml2.XMLHTTP.6.0')",
"ActiveXObject('Msxml2.XMLHTTP.3.0')",
"ActiveXObject('Msxml2.XMLHTTP')",
"ActiveXObject('Microsoft.XMLHTTP')"];
if( eval("''+/*@cc_on"+"@_jscript_version@*/-0")*1 === 5.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){}
}
})();
dom.partial = function(url){
var xhr = dom.xhr();
xhr.open("GET",url,false);
xhr.setRequestHeader("If-Modified-Since","0");
xhr.send(null);
return xhr.responseText|| ""
}
dom.tmpl = function(str,rLeft,rRight,sRight){
var arr = str.trim().split(rLeft),self = arguments.callee,buff = [],url,els,el,i = 0, n= arr.length;
while (i
if(els.indexOf(sRight) !== -1){//ここでels.length==2を使わないのはIEのsplitバグを避けるためです
switch (el[0].charAt(0)) {
case"#"://コメントの処理
break;
case"="//バックグラウンドで返される変数(ページに出力される)の処理;
buff.push(startOfHTML, el[0].substring(1), endOfHTML)
break;
ケース"://ローカルテンプレートの処理
url = el[0].substring(1).trim();
self[url] = self[url] || self.call(null,dom.partial(url),rLeft,rRight,sRight);
buff = buff.concat(dom.tmpl[url] );
break;
default:
buff.push(el[0], "
");
};
el[1] && buff.push(startOfHTML, dom.quote.call(null,el[1]), endOfHTML);
}else{
buff.push(startOfHTML, dom.quote.call(null,el[0]), endOfHTML);
}
}
return buff;
}
dom.ejs = function (obj) {
var sLeft = obj.left || "%>",
sRight = obj.right || "<%",
rLeft = new RegExp("\\s*"+sLeft+"\\s*"),
rRight = new RegExp("\\s*"+sRight+"\\s*"),
buff = ["var __views = [];
"],
key = obj.selector || obj.url,str;
if(obj.selector){
var el = document.getElementById(key);
if(!el)throw「ターゲット要素が見つからない」;
str = el.text;
}else{
str = dom.partial(key);
if(!str)throw「ターゲットファイルが存在しない」;
}
if(!dom.tmpl[key]){//セレクタ-->解析関数としてdom.tmpl関数にキャッシュ
buff = buff.concat(dom.tmpl.call(null,str,rLeft,rRight,sRight));
dom.tmpl[key] = new Function("json", "with(json){"+buff.join("") + '\t};return __views.join("");');
}
return dom.tmpl[key](obj.json || {});
};
window.dom = dom;
})();
window.onload = function(){
var els = [];
for(var i=0;i<1000;i++){
els.Push(「第」+i+「個の要素」)
}
var a = new Date
var data = dom.ejs({
selector:"tmpl",
left:"{{",
right:"}}",
json: {
name:「司徒正美」,
uls:els,
address:「異次元」
}
});
document.getElementById("tmplTC").innerHTML = data;
alert( new Date-a)
}
実行コード
今私は1つの考慮があって、テンプレートの規模の膨張に従って、中にますます多くの変数が混ざっているかもしれませんが、私たちはそれらのバックグラウンドから伝わったものをはっきり見分けることができません.それらは地元の臨時変数で、バックグラウンドの需要が変更されると、バックグラウンドのjsonデータも変更されます.これは維持が非常に難しい.だから私はrubyの変数の書く風格をとても鑑賞して、変数名からそれが実例の変数であることを知っていて、類の変数、普通の変数と定数、それは記号のこのものがあって、私はv 4バージョンに参加して@識別子を再加入します.