[转帖]Mootools源码分析-13 -- Class.Extras

原帖地址:http://space.flash8.net/space/?18713/viewspace-402523.html

原作者:我佛山人

 

/*
方法链式支持,链上的方法会依次执行,而不是同时执行,通常用于Fx及其派生类中
需要对目标类使用显示使用Imeplements实现,然后在相关位置调用callChain
*/
var Chain = new Class({

    
//对Implement Chain的对象,可以直接使用chain方法添加后续方法,主要是对外的接口
    chain: function()    {
        
this.$chain = (this.$chain || []).extend(arguments);
        
return this;
    },

    
//Implement对象本身的内部方法,使链式执行得以实现
    callChain: function()    {
        
return (this.$chain && this.$chain.length) ? this.$chain.shift().apply(this, arguments) : false;
    },

    
//清空链上所有等执行的方法
    clearChain: function()    {
        
if (this.$chain) this.$chain.empty();
        
return this;
    }

});

/*
类事件支持
对于自封装UI组件,它非常有用,而且是必需的,远比UWA的callback优雅得多
*/
var Events = new Class({

    
//添加单个事件
    addEvent: function(type, fn, internal)    {

        
//因为在options中使用onEventName : $empty,所以有此判断
        if (fn != $empty)    {
            
//使用||赋默认值
            this.$events = this.$events || {};
            
//使用||赋默认值
            this.$events[type] = this.$events[type] || [];
            
//数组的include方法
            this.$events[type].include(fn);
            
//是否内置事件
            if (internal) fn.internal = true;
        }
        
return this;
    },

    
//添加多个事件
    addEvents: function(events)    {
        
for (var type in events)    this.addEvent(type, events[type]);
        
return this;
    },

    
//触发事件
    fireEvent: function(type, args, delay)    {
        
if (!this.$events || !this.$events[type])    return this;
        
//数组的遍历,通知每个订阅对象
        this.$events[type].each(function(fn)    {
            fn.create({
'bind'this'delay': delay, 'arguments': args})();
        }, 
this);
        
return this;
    },

    
//移除单个事件
    removeEvent: function(type, fn)    {
        
//如果私有变量无值,表明不存在事件订阅,因此不需要处理
        if (!this.$events || !this.$events[type])    return this;

        
//非内置事件才擦除
        if (!fn.internal)    this.$events[type].erase(fn);
        
return this;
    },

    
//移除某个事件的所有订阅通知
    removeEvents: function(type)    {
        
for (var e in this.$events)    {
            
if (type && type != e)    continue;
            
var fns = this.$events[e];
            
for (var i = fns.length; i--; i)    this.removeEvent(e, fns[i]);
        }
        
return this;
    }

});

/*
构造函数可选参数支持,
需要对目标类使用显示使用Imeplements实现,然后在相关位置调用setOptions(通常在初始化的函数中)
*/
var ōptions = new Class({

    
/*
    将传入的参数与this.options中的默认参数合并
    其中以on打头紧跟一大写字母的参数,并且值为函数类型,将作为事件处理
    
*/
    setOptions: 
function()    {

        
//注意函数的run方法和数组的extend方法
        this.options = $merge.run([this.options].extend(arguments));

        
/*
        如果Implement了Events对象,会自动产生addEvent方法
        换言之,不具有addEvent方法的话,接下来的处理事件的代码便没了意义,因此返回
        
*/
        
if (!this.addEvent)    return this;
        
for (var option in this.options)    {

            
//仅当属性名on打头紧跟一大写字母的参数,并且值为函数类型,才作为事件处理
            if ($type(this.options[option]) != 'function' || !(/^on[A-Z]/).test(option))    continue;

            
//添加事件
            this.addEvent(option, this.options[option]);

            
//清除属性
            delete this.options[option];
        }
        
return this;
    }

});

 

posted @ 2009-10-29 09:14  webgis松鼠  阅读(254)  评论(0)    收藏  举报