可怜的笔记,耽误了N久,尽管是自己写的却也忘了一堆,记着那就写那吧,要不就忘成光棍了..
世界上,并没有AJAX,用的人多了,也就有人写出了这么一个名词罢了;
Ajax 部份,可以说是本框架中最复杂的一个部份,为了使框架具有良好的扩展性和可重用性,采用了固定模式,而不固定实现的方法,类似借鉴OOP中接口的一种实现方式. 数据传输上,尽量全部使用返回XMLDOM的方式而不使用返回文本,可能实现过程有些麻烦,但是可以回避对于乱码的处理等,并可以提供更好的数据完整性的保障;
// 根据XSL 将XML转换为HTML方法; xSystem.ajax.XmlToHtml = function(xml,xsl){ // FireFox 陷阱 if(xSystem.isIE) return xml.transformNode(xsl); var r = new XSLTProcessor(); r.importStylesheet(xsl); r.transformToDocument(xml); return new XMLSerializer().serializeToString(r.transformToDocument(xml)); } // 创建一个 xmlhttp 对像 xSystem.ajax.getRequest = function(){ var _XMLHTTP = ["Msxml2.XMLHTTP.6.0","Msxml2.XMLHTTP.5.0","Msxml2.XMLHTTP.4.0","MSXML2.XMLHTTP.3.0","MSXML2.XMLHTTP","Microsoft.XMLHTTP"]; var request; // 创建XMLHTTP对像 try{ if(xSystem.isIE){ for(var i=0;i < _XMLHTTP.length;i++){ try{ request = new ActiveXObject(_XMLHTTP[i]); break; }catch(e){} } }else{ request = new XMLHttpRequest(); } return request; }catch(e){ alert("无法创建DOM对像,请检查浏览器."); return false; } } // 创建一个XMLDOM对像 xSystem.ajax.getXMLDOM = function(){ this._DOMDocument=["Msxml2.DOMDocument.6.0","Msxml2.DOMDocument.5.0","Msxml2.DOMDocument.4.0","Msxml2.DOMDocument.3.0","MSXML2.DOMDocument","MSXML.DOMDocument","Microsoft.XMLDOM"]; try{ if(xSystem.isIE){ for(var i=0;i < this._DOMDocument.length;i++){ try{ this.request = new ActiveXObject(this._DOMDocument[i]); break; }catch(e){} } }else{ this.request =document.implementation.createDocument("","",null); } return this.request; }catch(e){ alert("无法创建DOM对像,请检查浏览器."); return false; } }
以上是最基本的几个方法,其它的另有专用的绑写回调方法,及几个简单的封装;
以下内容,是对一次请求时返回资源及相应处理方式的一个基本XML结构
<?xml version="1.0" encoding="utf-8"?>
<!-- 对一个页面的资源和可配置项的描述文件 -->
<page>
<!--
用户外部脚本,程序载入后将根据这些描述载入相应的外部文件,可以有多个userScript条目.
mode: [path|content] 属性确定内容的值是一个路径,还是文本正文;
type: [js|css] 属性确定内容的类型是CSS文件或JavaScript文件;
需要注意的是,由于在此处声明的资源,属于二次资源引用,所引用的脚本文件将在载入后运行,
所产生的载入延时及关联引用系统无法自动估计,建议此处尽量引用少量条目,而应把可以多次用
到的资源,在页面使用script 标签和link 标签完成,此处仅做为其它脚本的调用或执行入口。
-->
<userScript mode="path" type="js">demo.js</userScript>
<userScript mode="content" type="js">//alert("t0 hahaha");</userScript>
<userScript mode="path" type="css">demo.css</userScript>
<!--
用户自定义其下的内容,
name 属性,系统将使用这个属性在xSystem.globle中一个注册当前文档XMLDOM的资源,用
户在文档载入以后的任何地方使用xSystem.get(name)[0],可以来获取当前资源XMLDOM对像的引用。
-->
<content name="StringName"></content>
</page>
在这个XML中,描述了一个次固有请求的处理结果及相应功能及实现.每一个userScript 用于载入外部的相应JS,CSS等资源文件.content 节点中为具体的数据内容,框架将根据name属性,在xSystem.globle中注册该XML文档的DOM对像名称,使之可以在载入后的全局范围内都可以使用.userScript载入的脚本部份,并未作过多的限制,用户可以自由使用xSystem及子空间里定义的及注册的所有内容,并可以书写任意类型的JavaScript脚本.如定义函数,创建对像等,根据XML的可扩展性,在保证这个基本结构的前题下,可根据需要进行更复杂的扩展.
以下,摘自解析部份的一个小片段, FireFox浏览器默认不支持selectSingleNode方法,需要自己利用 XPathEvaluator 对像进行实现.
// 解析一个xpage,固有结构的XML文档 xdom:XMLDOM对像, args : 参数数组 xSystem.Xmodule.XPage = function(xdom,args){ //选取所有userScript节点 var scs = xdom.selectNodes("/page/userScript"); // 选取content节点 var scs1 = xdom.selectSingleNode("/page/content"); if(scs==null || scs1 ==null) return; // 使用content的name属性,在globle 空间中注册当前XMLDOM对像的引用 xSystem.set(scs1.selectSingleNode("./@name").nodeValue,[scs1,args]); // 遍历找到的userScript节点,并根据配置信息载入并执行相应的脚本或样式; for(var i=0;i < scs.length;i++){ switch(scs[i].selectSingleNode("./@mode").nodeValue){ // 如果定义模式,进行文档的处理,若mode的值为path 则表示该信息表示的是一个相应该件的路径; case "path": var f =xSystem.file.loadFile(scs[i].selectSingleNode("./child::text()").nodeValue,scs[i].selectSingleNode("./@type").nodeValue); try{ if(args[0] instanceof xSystem.module.layoutModule){ args[0]._files.push(f.href==undefined?f.src:f.href); } }catch(e){} break; // 若mode值为 content 则表示,其内容为一段可执行的JS代码文件 ps: 此处的content 是指mode 的值,而不是content节点; case "content": if(scs[i].selectSingleNode("//@type").nodeValue=="js"){ // 以windows对像为上下文,执行这段脚本; xSystem.util.runScript(xSystem.util.getTextData(scs[i])); } } } }
我们看到,在这里,并没有定义对content节点里所表示的数据进行处理,仅是把这个节点在globle空间中注册,我把处理的内容放到了载入的js文件当中. 所以,这个节点可以下可以为符合XML规范的任意内容,也可以为空,其注册的结果是一个二维数据,第一维永远只包括一个元素,即XMLDOM对像本身,第二维则由其它任何调用传入,根据调用上下文的不同,其内容可以为任意内容的数组,尽管我们只对content节点进行注册,但并不影响对整个文档DOM的引用,只需要通过ownerDocument 属性即可引用整个XMLDOM对像.