EXT的addListener,Ext.on做了些什么?

标签:, ,

Ext.on,其实就是Ext.lib.Event里的addListener方法,把addListener的代码拿出来晒晒先,大致过一遍,我下面一步步解释

  1. Ext.lib.Event = function() {
  2.         var listeners = [];//用来保存许多监听器的数组,每一行包含这4个:el, eventName, fn, wrappedFn,wrappedFn指的是将fn进行一个封装
  3.             addListener: function(el, eventName, fn) {
  4.                 el = Ext.getDom(el);
  5.                 if (!el || !fn) {
  6.                     return false;
  7.                 }
  8.  
  9.                 if ("unload" == eventName) {
  10.                     unloadListeners[unloadListeners.length] =
  11.                     [el, eventName, fn];
  12.                     return true;
  13.                 }
  14.  
  15.                 // prevent unload errors with simple check
  16.                 var wrappedFn = function(e) {
  17.                     return typeof Ext != 'undefined' ? fn(Ext.lib.Event.getEvent(e)) : false;
  18.                 };
  19.  
  20.                 var li = [el, eventName, fn, wrappedFn];
  21.  
  22.                 var index = listeners.length;
  23.                 listeners[index] = li;//将这4个东东保存进数组
  24.  
  25.                 this.doAdd(el, eventName, wrappedFn, false);
  26.                 //这里的doAdd是一个单例模式,this.doAdd其实返回一个函数引用,将这4个值传进那个函数里,那个函数是什么?那个函数就是正真绑定事件的函数!!往下看》》
  27.                 return true;
  28.  
  29.             },
  30.             doAdd: function () {
  31.                 if (window.addEventListener) {
  32.                     return function(el, eventName, fn, capture) {
  33.                         el.addEventListener(eventName, fn, (capture));
  34.                     };//那个函数在这里,这是FF的
  35.                 } else if (window.attachEvent) {
  36.                     return function(el, eventName, fn, capture) {
  37.                         el.attachEvent("on" + eventName, fn);
  38.                     };//那个函数在这里,这是IE的
  39.                 } else {
  40.                     return function() {
  41.                     };
  42.                 }
  43.             }()
  44.         }
  45. }();

再注意下 this.doAdd(el, eventName, wrappedFn, false);传进去的是一个wrappedFn,而不是用户指定的fn,为什么要这样呢?我们来看它的定义:
var wrappedFn = function(e) {
return typeof Ext != ‘undefined’ ? fn(Ext.lib.Event.getEvent(e)) : false;
};
其实它是返回了一个 fn(Ext.lib.Event.getEvent(e)) ,看看Ext.lib.Event.getEvent(e)的源码

  1. getEvent: function(e) {
  2.                 var ev = e || window.event;
  3.                 if (!ev) {
  4.                     var c = this.getEvent.caller;
  5.                     while (c) {
  6.                         ev = c.arguments[0];
  7.                         if (ev && Event == ev.constructor) {
  8.                             break;
  9.                         }
  10.                         c = c.caller;
  11.                     }
  12.                 }//上面在干嘛?其实也是为了兼容浏览器,确保事件e能够被取到!
  13.                 return ev;
  14.             },

总结下addListener做了哪些事情:
1、确保事件e被取到
2、将一些信息存进listeners数组
3、确保将事件绑定到element




已经有4个留言

  1. 初学者 Says @ 08-05-27 9:32 am

    有个地方看不懂:
    doAdd方法返回的是个函数,在这个函数里 el.attachEvent(”on” + eventName, fn);
    可是这个函数并没有执行啊,这样el并没有绑定上事件啊?是不是我漏了什么地方啊?

  2. crab Says @ 08-05-28 2:21 am

    你的确漏看一个地方

    this.doAdd(el, eventName, wrappedFn, false);

    这个doAdd不仅仅返回一个函数的引用,而且它还执行了这个函数。

    doAdd : function(){
    return : function(){};
    };
    这个写法是返回函数引用,就是你指的“没有执行呀”,的确没有执行,但是你再仔细看看,上面的写法其实是,

    doAdd : function(){
    return : function(){};
    }();

    明白了吧?

  3. 初学者 Says @ 08-05-28 2:52 am

    呵呵,谢谢指点。明白了。刚接触javascript oo编程,还要多学习,在你的blog里面学到不少东西,非常感谢。

  4. thinking Says @ 08-05-31 2:15 pm

    不明白ext的getEvent做这么多工作~~平常我们要得到event就是var ev = arguments[0] || window.event; 呵呵~~~




留言