读书人

仿服务器端脚本形式的JS模板实现方法

发布时间: 2012-11-06 14:07:00 作者: rapoo

仿服务器端脚本方式的JS模板实现方法

http://bbs.51js.com/thread-65160-1-1.html?

?

?

?

<html xmlns="http://www.w3.org/1999/xht...?
<head>?
<meta http-equiv="Content-Type" content="text/html; charset=gb2312" />?
<title>jssp演示</title>?
<script language="javascript">?
/**?
* @description:?
* 使用javascript模仿JSP的页面解析和运行,运行于客户端?
* 允许应用人员象开发JSP页面一样使用<%..%>?
* 允许页面动态包括子页面(同步读取页面)?
*?
**/?

//@--------------------------------- JSSP声明?
var jssp=function(){};?

/**?
* 页面缓存管理实例对象?
*/?
jssp.cacheInstance=null;?
/**?
* 页面加载实例对象?
*/?
jssp.pageLoaderInstance=null;?

/**?
* 在指定dom插入pagePath的执行后的页面内容?
*/?
jssp.render=function(pagePath,dom){?
if(typeof dom=="string") dom=document.getElementById(dom);?
var content=jssp.Core.run(pagePath);?
dom.innerHTML=content;?
}?

//@------------------------------------ JSSP运行配置?
/**?
* 引擎运行全局配置?
*/?
jssp.Config={};?
/**?
* 如果在客户端运行,是否缓存解析的页面?
*/?
jssp.Config.cachable=true;?
/**?
* 当jssp.Config.cacheable为true且在?
*/?
jssp.Config.cache$out.print( ";?
betweenPerc=true;?
isPrint=true;?
i+=2;?
}else if(nextTwo=="<%"&&nextThree!="<%="&&nextThree=="<%@"){?
i+=3;?
var directive="";?
while(nextTwo!="%>"){?
directive+=value.charAt(i);?
i++;?
if(i<=value.length-2){?
nextTwo=value.charAt(i)+value.charAt(i+1);?
}?
}?
strBuffer[point++]=escape(line)+"'));\n";?
line="";?
strBuffer[point++]=jssp.Core.parse._handleDirective(directive);?
strBuffer[point++]=" $out.print(unescape('";?
i++;?
}else if(nextTwo=="%>"){?
strBuffer[point++]=(isPrint?");":"")+"\n $out.print(unescape('";?
if(!betweenPerc) throw new jssp.Core.parse.ParseException("解析错误","必须用'%>'作为结束标签");?
betweenPerc=false;?
isPrint=false;?
i+=1;?
}else if(value.charAt(i)==String.fromCharCode(10)){?
if(!betweenPerc){?
strBuffer[point++]=escape(line)+"\\n'));\n"+" $out.print(unescape('";?
line="";?
lineNumber++;?
}?
}else if(value.charAt(i)==String.fromCharCode(13)){?
if(betweenPerc) strBuffer[point++]="\n";?
}else{?
if(betweenPerc)?
strBuffer[point++]=value.charAt(i);?
else?
line+=value.charAt(i);?
}?
}?
strBuffer[point++]=escape(line)+"'));\n";?
strBuffer[point++]="}catch(e){\n";?
strBuffer[point++]="return '"+"执行页面发生异常.异常类型:'+e.name+'. 错误消息: '+e.message;\n";?
strBuffer[point++]="}\n";?
strBuffer[point++]="if(!$context.isIncluded) return $out.flush();\n";?
strBuffer[point++]="}\n";?
}catch(e){?
point=0;?
strBuffer=[];?
strBuffer[point++]="function($context){\n";?
strBuffer[point++]="return \""+"An exception occurred while parsing on line "+lineNumber+". Error type: "+e.name+". Error message: "+e.message+"\";";?
strBuffer[point++]="}";?
}?
var out=strBuffer.join("");?
return out;?
}?
/**?
* 解析指示头?
*/?
jssp.Core.parse._handleDirective=function(directive){?

var i = 0;?

var tolkenIndex = 0;?
var tolken = new Array();?

//Skip first spaces;?
while ( directive.charAt(i) == ' ' ) {?
i++;?
}?

tolken[tolkenIndex] = "";?
while ( directive.charAt(i) != ' ' && i <= directive.length ) {?
tolken[tolkenIndex] += directive.charAt(i);?
i++;?
}?

tolkenIndex++;?

//Skip first spaces;?
while ( directive.charAt(i) == ' ' ) {?
i++;?
}?

tolken[tolkenIndex] = "";?
while ( directive.charAt(i) != ' ' && directive.charAt(i) != '=' && i <= directive.length ) {?
tolken[tolkenIndex] += directive.charAt(i);?
i++;?
}?

tolkenIndex++;?

//Skip first spaces;?
while ( directive.charAt(i) == ' ' ) {?
i++;?
}?

if( directive.charAt(i) != '=' )?
throw new jssp.Core.parse.ParseException("Sintax error", "Tolken = expected attribute");?
i++?

//Skip first spaces;?
while ( directive.charAt(i) == ' ' ) {?
i++;?
}?

tolken[tolkenIndex] = "";?
while ( directive.charAt(i) != ' ' && i <= directive.length ) {?
tolken[tolkenIndex] += directive.charAt(i);?
i++;?
}?
tolkenIndex++;?

//Skip first spaces;?
while ( directive.charAt(i) == ' ' && i <= directive.length ) {?
i++;?
}?

tolken[tolkenIndex] = "";?
while ( directive.charAt(i) != ' ' && directive.charAt(i) != '=' && i <= directive.length && i <= directive.length ) {?
tolken[tolkenIndex] += directive.charAt(i);?
i++;?
}?

tolkenIndex++;?

if( directive.charAt(i) != '=' && i <= directive.length )?
throw new jssp.Core.parse.ParseException("Sintax error", "Tolken = expected after attribute" );?
i++?

tolken[tolkenIndex] = "";?
while ( directive.charAt(i) != ' ' && i <= directive.length && i <= directive.length ) {?
tolken[tolkenIndex] += directive.charAt(i);?
i++;?
}?

var file = "";?
var context = "";?

if ( tolken[0] != "include" )?
throw new jssp.Core.parse.ParseException("Sintax error","Directive " + tolken[0] + " unknown.") ;?

if ( tolken[1] != "file" )?
throw new jssp.Core.parse.ParseException("Sintax error", "Attribute file expected after include." );?
else file = tolken[2];?

if ( tolken[3] != "context" && tolken[3] != "" )?
throw new jssp.Core.parse.ParseException( "Sintax error", "Attribute context expected after file.");?
else if ( tolken[3] == "context" )?
context = tolken[4]?
else?
context = "$context";?

var out = "$context.include(" + file + ");\n";?

return out;?
}?

/**?
* 解析异常?
*/?
jssp.Core.parse.ParseException=function(name,message) {?
this.name=name;?
this.message=message;?
}?
//@--------------------------------------------页面内容加载接口定义?
/**?
* 页面内容加载类接口定义?
*/?
jssp.Core.PageLoader=function(){}?
/**?
* 读取页面文本?
*/?
jssp.Core.PageLoader.prototype.loadPage=function(pagePath){throw "不能直接调用接口或您还未实现此方法!";}?
//@--------------------------------------------页面运行实现方法?
/**?
* @param pagePath 加载页面?
* @parma context 上下文对象?
*/?
jssp.Core.run=function(pagePath,context){?

if(!jssp.pageLoaderInstance){?
//jssp引擎初始化?
if(jssp.Config.cachable) jssp.cacheInstance=eval("new "+jssp.Config.cacheClass+"();");?
jssp.pageLoaderInstance=eval("new "+jssp.Config.pageLoaderClass+"();");?
}?

var key=pagePath;if(key.indexOf("?")>0) key=key.substring(0,key.indexOf("?"));?

var processer=jssp.Config.cachable?jssp.cacheInstance.get(key):null;?
if(!processer){?
eval("processer="+jssp.Core.parse(jssp.pageLoaderInstance.loadPage(pagePath)));?
if(jssp.Config.cachable) jssp.cacheInstance.set(key,processer);?
}else{?
//alert("cache")?
}?

if(!context)?
context=new jssp.Context(pagePath);?
else?
context=new jssp.Context(pagePath,context);?
return processer(context);?
}?
//@-----------------------------------------------AJAX加载页面实现?
jssp.Core.PageLoader.Ajax=function(){}?

jssp.Core.PageLoader.Ajax.prototype.loadPage=function(pagePath){?
var content=jssp.Ajax.send(pagePath,"GET",false);?
if(!content) {?
alert("请求页面:"+pagePath+" 返回为null!");return null;?
}?
return content;?
}?
//@-----------------------------------------------AJAX操作实现?
jssp.Ajax=function(){}?
/**?
* 建立HTTP连接?
*/?
jssp.Ajax.createHttpRequest=function(){?
if(window.XMLHttpRequest)?
return new XMLHttpRequest();?
var request=null;?
try{?
request=new ActiveXObject("Msxml2.XMLHTTP.4.0");?
}catch(e){?
try{?
request=new ActiveXObject("Msxml2.XMLHTTP");?
}catch(e){?
try{?
request=new ActiveXObject("microsoft.XMLHTTP");?
}catch(e){?
throw "XMLHTTPRequest组件客户端不支持!";?
}?
}?
}?
return request;?
}?

/**?
* 发送AJAX请求?
* @param url 请求页面?
* @param method 请求方法 get or post?
* @param async 是否为异步调用?
* @param callback 回调函数?
* @param preHook 调用前执行函数?
* @param postHook 调用后请求返回执行函数?
*/?
jssp.Ajax.send=function(url,method,async,callback,preHook,postHook){?
method=method.toUpperCase();?

if(typeof preHook=="function") preHook();?

var request=jssp.Ajax.createHttpRequest();?
request.open(method,url,async);?
if(async){?
if(typeof callback!="function") throw "必须要设置回调函数";?
request.onreadystatechange=function(){?
jssp.Ajax.callback(request,callback,postHook);?
};?
}?
request.send(null);?
if(!async) {?
if(request.status==200||request.status==304)?
return jssp.Ajax._chartset(request);?
else?
return null;?
}?
}?
/**?
* 接受响应,调用自定义回调函数?
*/?
jssp.Ajax.callback=function(response,callback,postHook){?
if(response.readyState!=4) return;?
var text;?
if(response.status==200||response.status==304){?
text=jssp.Ajax._chartset(response);?
}?
callback(text);?
if(typeof postHook=="function") postHook();?
}?
/**?
* 中文乱码处理?
*/?
jssp.Ajax._chartset=function(r){?
var t=bytes2BSTR(r.responseBody);?
return t;?
}?

</script>?

<script language="javascript">?
jssp.Config.pageLoaderstyle="width:100%;" rows="15">?
<table width="100%" border="0" align="center" cellpadding="4" cellspacing="2">?
<tr>?
<td align="center" valign="middle" bgcolor="#666699"><span valign="middle" bgcolor="#666699"><span valign="middle" bgcolor="#666699"><span valign="middle" bgcolor="#666699"><span valign="middle" ><%=i%></td>?
<td align="center" valign="middle" ><%=Math.random()%></td>?
<td align="center" valign="middle" ><%=Math.random()%></td>?
<td align="center" valign="middle" ><%=Math.random()%></td>?
</tr>?
<%}%>?
</table>?
<%?
window.alert("耗时:"+(new Date()-beginTime)+"ms");?
%>?
</textarea>?
<button onClick="showPage()">显示内容</button>?
<hr>?
<div id="pageArea"></div>?
</hr>?

</body>?
</html>

1 楼 renjie120 2011-01-17 没有使用的例子么?这样不容易看出来有什么实际的用途.

读书人网 >JavaScript

热点推荐