[转帖]Mootools源码分析-34 -- Request.HTML

原帖地址: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], truetrue);
                
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;
    }
});

 

posted @ 2009-11-25 14:17  webgis松鼠  阅读(543)  评论(0编辑  收藏  举报