日期:2014-05-16  浏览次数:20441 次

ExtJs源码分析与学习—ExtJs事件机制(三)

这篇讲ExtJs对事件的管理和调用

?

????? ExtJs对事件的管理非常强大,主要定义在Ext.EventManager对象(单例模式)中。先看注册事件监听方式,ExtJs提供了几种方式来注册元素监听函数

  • 通过Ext.EventManager.addListener/on函数来为指定元素的某种事件注册监听函数。例如:Ext.EventManager.on('test1','click',clickMe,this);// clickMe是要执行的函数
  • 通过ExtJs 元素的on函数来为自身注册某种事件的监听处理函数。例如:
    Ext.get('test1').on('click', clickMe,this,{preventDefault:true});
  • 通过Ext.addBehaviors函数为多个元素的多个事件注册监听处理函数,该方法在ExtJs源码分析与学习—ExtJs核心代码扩展中已介绍过。?

具体来说可分为
??? 标准配置方式
el.on(eventName,fn,scope,options);
options参数是事件配置项,各项说明如下:
scope : 可指定执行上下文
delegate :事件代理
stopEvent :阻止冒泡和默认行为
preventDefault :阻止默认行为
stopPropagation :停止事件冒泡
normalized : 仅传原生事件对象
delay :延迟执行
single : 仅执行一次
buffer :延迟执行,多次时最后一次覆盖前一次
target : 指定在父元素上执行


???私有配置多事件注册
el.on({'click':{fn:this.onClick,scope:this,delay:100},
???? 'mouseover':{fn:this.onMouseOver,scope:this},
???? …
??? });


? 共享配置多事件注册
el.on({'click':this. onClick,
???? 'mouseover':this.onMouseOver,
???? …,
???? scope:this});


?? 多元素多事件注册
Ext. addBehaviors({
'#foo a@click' : function(e, t){
??????? // do something
},
'#foo a, #bar span.some-class@mouseover' : function(){
??????? // do something
}
);
注意这种共享配置多事件注册监听函数只有两个参数,不能传递配置对象来进行配置,与前三种不同。

?

上述几种方式最终还是调用Ext.EventManager.addListener函数来注册监听的,该函数源代码如下:

?

        /**
         * 加入一个事件处理函数,方法{@link #on}是其简写方式。
         * @param {String/HTMLElement} element 要分配的html元素或者其id。
         * @param {String} eventName 事件处理函数的名称。
         * @param {Function} fn 事件处理函数。该函数会送入以下的参数
         * @param {Object} scope (optional) (可选的)事件处理函数执行时所在的作用域。处理函数“this”的上下文
         * @param {Object} options (optional) (可选的) 包含句柄配置属性的一个对象。该对象可能会下来的属性:
         * 调用addListener时送入的选项对象。
         * <li>scope : Object 事件处理函数执行时所在的作用域。处理函数“this”的上下文环境。
         * <li>delegate : String 一个简易选择符,用于过滤目标,或是查找目标的子孙。
         * <li>stopEvent : Boolean true表示为阻止事件。即停止传播、阻止默认动作。
         * <li>preventDefault : Boolean true表示为阻止默认动作。
         * <li>stopPropagation : Boolean true表示为阻止事件传播。
         * <li>normalized : Boolean false表示对处理函数送入一个原始、未封装过的浏览器对象而非标准的
         * <li>delay : Number  触发事件后处理函数延时执行的时间。
         * <li>single : Boolean true代表为下次事件触发加入一个要处理的函数,然后再移除本身。
         * <li>buffer : Number 若指定一个毫秒数会把该处理函数安排到{@link Ext.util.DelayedTask}延时之后才执行。 
         */

    addListener : function(element, eventName, fn, scope, options){
            if(typeof eventName == 'object'){//事件名为对象,说明采用配置多事件注册
                var o = eventName, e, val;
                for(e in o){
                    val = o[e];
                    if(!propRe.test(e)){//非标准模式下不能使用私有自定义的配置项,如options配置了{msg:'提示信息'}
                        if(Ext.isFunction(val)){
                            // shared options 共享配置项
                            listen(element, e, o, val, o.scope);
                        }else{
                            // individual options 私有配置项
                            listen(element, e, val);
                        }
                    }
                }
            } else {
                listen(element, eventName, options, fn, scope);//标准配置项
            }
        },

?

?

?该监听函数统一调用了listen,源代码如下:

?

    /**
     * @param {} element 要注册监听事件的元素
	 * @param {} ename 事件名
	 * @param {} opt 配置项
	 * @param {} fn 监听函数
	 * @param {} scope 上下文(作用域)
	 * @return {}
     */
    var listen = function(element, ename, opt, fn, scope){
        var o = (!opt || typeof opt == "b