Ext 详解--查看文章
 
读Ext源码之九(事件管理)
发布时间:2010-12-15
  • 上一篇文章:
  • 下一篇文章: 没有了

  • Ext的事件管理非常强大。主要定义在Ext.EventManager对象(单例模式)中。该对象有以下方法

    addListener
    removeListener
    removeAll
    getListeners
    purgeElement
    _unload
    onDocumentReady
    on
    un
    stoppedMouseDownEvent


    on / un 是 addListener / removeListener的快捷方式 。
    stoppedMouseDownEvent 是  Ext.util.Event 类的实例对象,这个类定义在Observable.js中。
    stoppedMouseDownEvent 在Ext.EventObject 类中用到。

    使用Ext.EventManager.on添加事件很简单

     

    Html代码 复制代码
    1. <p id="p1" style="background:gold;">  
    2.     HELLO   
    3. </p>  
    4.   
    5. <script type="text/javascript">  
    6.     var p1 = document.getElementById('p1');   
    7.     function f1(){alert(this)}   
    8.     Ext.EventManager.on(p1,'click',f1);    
    9. </script>  

     

    这样就为段落P添加了一个单击事件。默认情况下执行上下文就是HtmlElement自身。当然可以使用第四个参数scope指定上下文。

     

    Js代码 复制代码
    1. <script type="text/javascript">   
    2.     var p1 = document.getElementById('p1');   
    3.     function f1(){alert(this)}   
    4.     Ext.EventManager.on(p1,'click',f1,window);     
    5. </script>  

     

    第五个参数是个对象,属性介绍分别如下:
    scope : 可指定执行上下文
    delegate :事件代理
    stopEvent :阻止冒泡和默认行为
    preventDefault :阻止默认行为
    stopPropagation :停止事件冒泡
    normalized : 仅传原生事件对象
    delay :延迟执行
    single : 仅执行一次
    buffer :延迟执行,多次时最后一次覆盖前一次
    target : 指定在父元素上执行

     

    下图是Ext.EventManager.addListener的详细接口说明

     

     

     

    下面看看源码是如何实现的

     

    Js代码 复制代码
    1. addListener : function(element, eventName, fn, scope, options){   
    2.     if(Ext.isObject(eventName)){   
    3.         var o = eventName, e, val;   
    4.         for(e in o){   
    5.             val = o[e];   
    6.             if(!propRe.test(e)){   
    7.                 if(Ext.isFunction(val)){   
    8.                     // shared options   
    9.                     listen(element, e, o, val, o.scope);   
    10.                 }else{   
    11.                     // individual options   
    12.                     listen(element, e, val);   
    13.                 }   
    14.             }   
    15.         }   
    16.     } else {   
    17.         listen(element, eventName, options, fn, scope);   
    18.     }   
    19. },  
     

    可以看到其中调用私有 listen 函数,但存在三种分支情况。暂且考虑第三者情况listen(element, eventName, options, fn, scope);

    listen 函数定义如下

     

    Js代码 复制代码
    1. function listen(element, ename, opt, fn, scope){   
    2.     var o = !Ext.isObject(opt) ? {} : opt,   
    3.         el = Ext.getDom(element), task;   
    4.   
    5.     fn = fn || o.fn;   
    6.     scope = scope || o.scope;   
    7.   
    8.     if(!el){   
    9.         throw "Error listening for \"" + ename + '\". Element "' + element + '" doesn\'t exist.';   
    10.     }   
    11.     function h(e){   
    12.         // prevent errors while unload occurring   
    13.         if(!Ext){// !window[xname]){  ==> can't we do this?   
    14.             return;   
    15.         }   
    16.         e = Ext.EventObject.setEvent(e);   
    17.         var t;   
    18.         if (o.delegate) {   
    19.             if(!(t = e.getTarget(o.delegate, el))){   
    20.                 return;   
    21.             }   
    22.         } else {   
    23.             t = e.target;   
    24.         }   
    25.         if (o.stopEvent) {   
    26.             e.stopEvent();   
    27.         }   
    28.         if (o.preventDefault) {   
    29.            e.preventDefault();   
    30.         }   
    31.         if (o.stopPropagation) {   
    32.             e.stopPropagation();   
    33.         }   
    34.         if (o.normalized) {   
    35.             e = e.browserEvent;   
    36.         }   
    37.   
    38.         fn.call(scope || el, e, t, o);   
    39.     };   
    40.     if(o.target){   
    41.         h = createTargeted(h, o);   
    42.     }   
    43.     if(o.delay){   
    44.         h = createDelayed(h, o, fn);   
    45.     }   
    46.     if(o.single){   
    47.         h = createSingle(h, el, ename, fn, scope);   
    48.     }   
    49.     if(o.buffer){   
    50.         task = new Ext.util.DelayedTask(h);   
    51.         h = createBuffered(h, o, task);   
    52.     }   
    53.   
    54.     addListener(el, ename, fn, task, h, scope);   
    55.     return h;   
    56. };  

     

    比较长,执行流程如下

    1,options参数未传,使用空对象{}。(接口的第5个参数)
    2,通过Ext.getDom获取HTMLElement元素(接口的第1个参数)。
    3, 响应函数先取fn(接口的第3个参数),没传则取opt.fn上。
    4, 执行上下文先取scope(接口的第4个参数),没有则取opt.scope。
    5,el不存在,抛异常
    6, 内部函数h包装了客户端传入的函数fn,将原生事件对象偷偷转换成Ext包装后的事件对象Ext.EventObject。依次根据所传opt参数进行对应的操作。最后一句是核心

    Js代码 复制代码
    1. fn.call(scope || el, e, t, o);  


    响应函数fn真正的执行。

    7, 根据opt参数进行对应的操作:o.target,o.delay,o.single和o.buffer。
    8, 调用私有的addListener函数。

    私有的addListener定义如下:

     

    Js代码 复制代码
    1. /// There is some jquery work around stuff here that isn't needed in Ext Core.   
    2. function addListener(el, ename, fn, task, wrap, scope){   
    3.     el = Ext.getDom(el);   
    4.     var id = getId(el),   
    5.         es = Ext.elCache[id].events,   
    6.         wfn;   
    7.     wfn = E.on(el, ename, wrap);   
    8.     es[ename] = es[ename] || [];   
    9.   
    10.     /* 0 = Original Function,  
    11.        1 = Event Manager Wrapped Function,  
    12.        2 = Scope,  
    13.        3 = Adapter Wrapped Function,  
    14.        4 = Buffered Task  
    15.     */  
    16.     es[ename].push([fn, wrap, scope, wfn, task]);   
    17.   
    18.   
    19.     // this is a workaround for jQuery and should somehow be removed from Ext Core in the future   
    20.     // without breaking ExtJS.   
    21.     if(ename == "mousewheel" && el.addEventListener){ // workaround for jQuery   
    22.         var args = ["DOMMouseScroll", wrap, false];   
    23.         el.addEventListener.apply(el, args);   
    24.         Ext.EventManager.addListener(WINDOW, 'unload'function(){   
    25.             el.removeEventListener.apply(el, args);   
    26.         });   
    27.     }   
    28.     if(ename == "mousedown" && el == document){ // fix stopped mousedowns on the document   
    29.         Ext.EventManager.stoppedMouseDownEvent.addListener(wrap);   
    30.     }   
    31. };  

     

     

    该函数中最重要一句

    Js代码 复制代码
    1. wfn = E.on(el, ename, wrap);  

     


    E.on 是 Ext.lib.Event.on,对事件的低级封装。

    此外将返回对象wfn存在数组中。

    整个Ext添加事件的调用流程就是如此..



     [Ext 详解]extJs 2.0学习笔记(Ext.Element API总结) (佚名,07-21)
     Ext.Element API比较多,大伙用的时候也难以在短时间把住它的脉络,主要功能。这个给个总结,而不是一个API说明。说到API说明,网上早有大侠做得蛮不错的了。 位置设置:getX()   取得相对于页面的x坐标getY()   取得相对于……

     [Ext 详解]EXT学习经验分享:深刻理解EXT与服务器端的交互 (未知,08-30)
    EXT是一款强大的AJAX框架,其UI设计非常华丽,所以在对UI要求高的项目中可以使用!        前面一段时间发了一篇封装的EXT CRUD面板,地址为http://www.phpchina.com/bbs/thread-59552-……

     [Ext 详解]extJs 2.0学习笔记(Ajax篇) (佚名,07-21)
    一听到Ajax,我与大家一样,如雷贯耳,都说XXX Ajax框架,事实上,这一部分内容在ExtJs中是基础中的基础,就那个样。这儿主要是讨论一些资料、书本都不会涉及的领域。这些东西平常只能由自己摸索的。   在此话题之先,先解决一个问题,现在用asp.net的人多了,但是,用asp.net ajax……

     [Ext 详解][组图]Ext window的大小与屏幕匹配 (myext,07-04)
    网页可见区域宽:document.body.clientWidth 网页可见区域高:document.body.clientHeight 网页可见区域宽:document.body.offsetWidth (包括边线的宽) 网页可见区域高:document.body.offsetHeight (包括……

     [Ext 详解][转载]EXT核心API详解(五)- EventManager/EventObject (佚名,07-20)
    Ext.EventManager事件管理者中的大部分方法都在Ext中有定义,主要用于事件管理addListener( String/HTMLElement el, String eventName, Function handler,on( String/HTMLElement el, String……

     


    ©2008 MyExt.cn
    本站文章来自互联网,仅供学习和研究使用,如有版权问题,请发送Email:myext@126.com.