原帖地址:http://space.flash8.net/space/?uid-18713-action-viewspace-itemid-407193
原作者:我佛山人
//
响应输出为HTML的Ajax请求类
Request.HTML = new Class({
// 继承自Request类
Extends: Request,
options: {
// 是否更新
update: false ,
// 是否解释执行字符脚本
evalscrīpts: true ,
// 是否过滤
filter: false
},
// 处理HTML代码
processHTML: function (text) {
// 如果请求为完整的HTML页
var match = text.match( / <body[^>]*>([\s\S]*?)<\ / body > / i);
// 取<body>与</body>之间的字符
text = (match) ? match[ 1 ] : text;
// 创建html的容器节点
var container = new Element( ' div ' );
// 返回容器节点,先尝试使用XMLDOM解释HTML节点,失败的话直接设置innerHTML
return $ try ( function () {
// 构造一个根节点,因为必须保证让XML片段有根节点
var root = ' <root> ' + text + ' </root> ' , doc;
// IE的处理
if (Browser.Engine.trident) {
// 使用ActiveX控件解释
doc = new ActiveXObject( ' Microsoft.XMLDOM ' );
// 同步加载
doc.async = false ;
doc.loadXML(root);
} else {
// 使用标准DOM解释器解释
doc = new DOMParser().parseFromString(root, ' text/xml ' );
}
// 取根节点句柄
root = doc.getElementsByTagName( ' root ' )[ 0 ];
// 通过遍历节点,复制到container容器中
for ( var i = 0 , k = root.childNodes.length; i < k; i ++ ) {
var child = Element.clone(root.childNodes[i], true , true );
if (child) container.grab(child);
}
return container;
// XMLDOM解释失败的话直接设置innerHTML
}) || container.set( ' html ' , text);
},
// 请求成功,覆盖Request类的同名方法
success: function (text) {
var options = this .options, response = this .response;
// 解释出脚本,之后剩下HTML
response.html = text.stripscrīpts( function (scrīpt) {
response.javascrīpt = scrīpt;
});
// 处理HTML中的节点
var temp = this .processHTML(response.html);
// 绑定节点到返回的对象
response.tree = temp.childNodes;
response.elements = temp.getElements( ' * ' );
// 如果提供过滤标签名,过滤树节点
if (options.filter) response.tree = response.elements.filter(options.filter);
// 如果指定需要更新的Element,将响应更新到Element
if (options.update) $(options.update).empty().adopt(response.tree);
// 如果指定解释脚本
if (options.evalscrīpts) $exec(response.javascrīpt);
// 调用父类方法,触发成功事件
this .onSuccess(response.tree, response.elements, response.html, response.javascrīpt);
}
});
// 为Element添加load属性的setter和getter
Element.Properties.load = {
// setter
set: function (options) {
// 从临时对象取Request.HTML
var load = this .retrieve( ' load ' );
// 如果对象存在,取消(这里的send貌似是load的手误?)
if (load) send.cancel();
// 缓存Request.HTML的配置参数
return this .eliminate( ' load ' ).store( ' load:options ' , $extend({data: this , link: ' cancel ' , update: this , method: ' get ' }, options));
},
// getter
get: function (options) {
// 如果提供配置参数或者不存在缓存
if (options || ! this .retrieve( ' load ' )) {
// 缓存配置参数
if (options || ! this .retrieve( ' load:options ' )) this .set( ' load ' , options);
// 缓存Request.HTML对象
this .store( ' load ' , new Request.HTML( this .retrieve( ' load:options ' )));
}
// 返回缓存的Request.HTML对象
return this .retrieve( ' load ' );
}
};
// 为Element增加load方法
Element.implement({
// 加载远程页面节点到当前Element内
load: function () {
// 上面的准备工作合取load能得到Request.HTML实例,然后发送
// 注意Array.link的使用,使send的两个参数可以任意排列,并且可选
this .get( ' load ' ).send(Array.link(arguments, {data: Object.type, url: String.type}));
return this ;
}
});
Request.HTML = new Class({
// 继承自Request类
Extends: Request,
options: {
// 是否更新
update: false ,
// 是否解释执行字符脚本
evalscrīpts: true ,
// 是否过滤
filter: false
},
// 处理HTML代码
processHTML: function (text) {
// 如果请求为完整的HTML页
var match = text.match( / <body[^>]*>([\s\S]*?)<\ / body > / i);
// 取<body>与</body>之间的字符
text = (match) ? match[ 1 ] : text;
// 创建html的容器节点
var container = new Element( ' div ' );
// 返回容器节点,先尝试使用XMLDOM解释HTML节点,失败的话直接设置innerHTML
return $ try ( function () {
// 构造一个根节点,因为必须保证让XML片段有根节点
var root = ' <root> ' + text + ' </root> ' , doc;
// IE的处理
if (Browser.Engine.trident) {
// 使用ActiveX控件解释
doc = new ActiveXObject( ' Microsoft.XMLDOM ' );
// 同步加载
doc.async = false ;
doc.loadXML(root);
} else {
// 使用标准DOM解释器解释
doc = new DOMParser().parseFromString(root, ' text/xml ' );
}
// 取根节点句柄
root = doc.getElementsByTagName( ' root ' )[ 0 ];
// 通过遍历节点,复制到container容器中
for ( var i = 0 , k = root.childNodes.length; i < k; i ++ ) {
var child = Element.clone(root.childNodes[i], true , true );
if (child) container.grab(child);
}
return container;
// XMLDOM解释失败的话直接设置innerHTML
}) || container.set( ' html ' , text);
},
// 请求成功,覆盖Request类的同名方法
success: function (text) {
var options = this .options, response = this .response;
// 解释出脚本,之后剩下HTML
response.html = text.stripscrīpts( function (scrīpt) {
response.javascrīpt = scrīpt;
});
// 处理HTML中的节点
var temp = this .processHTML(response.html);
// 绑定节点到返回的对象
response.tree = temp.childNodes;
response.elements = temp.getElements( ' * ' );
// 如果提供过滤标签名,过滤树节点
if (options.filter) response.tree = response.elements.filter(options.filter);
// 如果指定需要更新的Element,将响应更新到Element
if (options.update) $(options.update).empty().adopt(response.tree);
// 如果指定解释脚本
if (options.evalscrīpts) $exec(response.javascrīpt);
// 调用父类方法,触发成功事件
this .onSuccess(response.tree, response.elements, response.html, response.javascrīpt);
}
});
// 为Element添加load属性的setter和getter
Element.Properties.load = {
// setter
set: function (options) {
// 从临时对象取Request.HTML
var load = this .retrieve( ' load ' );
// 如果对象存在,取消(这里的send貌似是load的手误?)
if (load) send.cancel();
// 缓存Request.HTML的配置参数
return this .eliminate( ' load ' ).store( ' load:options ' , $extend({data: this , link: ' cancel ' , update: this , method: ' get ' }, options));
},
// getter
get: function (options) {
// 如果提供配置参数或者不存在缓存
if (options || ! this .retrieve( ' load ' )) {
// 缓存配置参数
if (options || ! this .retrieve( ' load:options ' )) this .set( ' load ' , options);
// 缓存Request.HTML对象
this .store( ' load ' , new Request.HTML( this .retrieve( ' load:options ' )));
}
// 返回缓存的Request.HTML对象
return this .retrieve( ' load ' );
}
};
// 为Element增加load方法
Element.implement({
// 加载远程页面节点到当前Element内
load: function () {
// 上面的准备工作合取load能得到Request.HTML实例,然后发送
// 注意Array.link的使用,使send的两个参数可以任意排列,并且可选
this .get( ' load ' ).send(Array.link(arguments, {data: Object.type, url: String.type}));
return this ;
}
});