日志文章

2008年02月04日 09:19:11

Ext架构分析(1)--理解Ext.util.Event

  由于Ext2.0中所有的组件都是由Observable继承而来,理解Ext就需要先从Ext.util.Observable说起,而Observable是对Event对象进行管理,从而理解Observable必须首先从Ext.util.Event说起。
  Ext.util.Event是一个封装的非常精致的对象,但和你想象的不同,Event同任何的HTML DOM元素没有任何的关系(尽管Ext是处理HTML元素的),实际上,它是一个通用的事件及其事件的处理的对象。 也许有朋友要问,HTML Element本身已经支持了事件,为什么还要再重新设计一套Event机制呢?其实,基本上所有的javascript框架都会实现自己的Event机制,原因很多,但是至少有一点:HTML元素对于事件的处理是通过简单的单一绑定实现,也就是说,如果不进行任何的封装,你的事件只能唯一的绑定到一个事件处理句柄,举个例子:
  var e=document.getElementById("test");
  e.onclick=function(){alert("handle1")};
  e.onclick=function(){alert("handle2")};
  运行的结果你回发现,只会弹出一个"handle2"的alert框,因为第一个事件已经被第二个事件重载了。而使用Ext框架,你可以放心的解决这个问题,同一个事件可以依次被绑定到多个事件处理句柄上。
  Ext.util.Event对象构建器需要传入两个对象:obj(处理事件的缺省对象),name(事件名称)。在构建Event对象时,Event对象会同时构建一个事件的处理函数的数组:listeners,通过这个数组实现了一个事件的多个事件句柄函数的处理。
Ext.util.Event = function(obj, name){
  this.name = name;
  this.obj = obj;
  this.listeners = [];
};

通过Event的fire方法就可以依次触发该数组中的处理函数。 实际上,fire方法在遍历listeners数组中的处理函数过程中,只要处理函数的返回值为false,则不再继续运行后续的处理函数。所以,可以通过检查fire方法的返回值得知事件处理函数是否完全被运行。
  fire : function(){
    var ls = this.listeners, scope, len = ls.length;
    if(len > 0){
      this.firing = true;//通过firing可以保证多个事件处理函数不会并发运行
      var args = Array.prototype.slice.call(arguments, 0);//slice方法可以有效的进行数组的克隆
      for(var i = 0; i < len; i++){
        var l = ls;
        //事件的处理,只要有一个处理函数返回false,整个事件处理就被停止
        if(l.fireFn.apply(l.scope||this.obj||window, arguments) === false){
          this.firing = false;
          return false;
        }
      }
      this.firing = false;
    }
    return true;
  }

  Event可以通过addListener、removeListener、clearListeners(移除所有的事件处理函数)方法对listeners进行管理。但是,Listener中保存的事件处理函数实际上并不是addListener传递的函数,实际上,addListener传入的方法通过createListener对事件的处理函数进行了封装,通过封装,实现了对通一个重复事件的的三种不同处理方式:delay(延迟运行)、single(移除Listener中的处理函数,仅运行当前的处理函数)、buffer(避免重复运行处理函数)。
  createListener : function(fn, scope, o){
    o = o || {};
    scope = scope || this.obj;
    var l = {fn: fn, scope: scope, options: o};
    var h = fn;
    if(o.delay){
      h = createDelayed(h, o, scope);
    }
    if(o.single){
      h = createSingle(h, this, fn, scope);
    }
    if(o.buffer){
      h = createBuffered(h, o, scope);
    }
    l.fireFn = h;
    return l;
  }


  var createBuffered = function(h, o, scope){
    var task = new Ext.util.DelayedTask();
    return function(){
        task.delay(o.buffer, h, scope, Array.prototype.slice.call(arguments, 0));
    };
  };

  var createSingle = function(h, e, fn, scope){
    return function(){
        e.removeListener(fn, scope);
        return h.apply(scope, arguments);
    };
  };

  var createDelayed = function(h, o, scope){
    return function(){
        var args = Array.prototype.slice.call(arguments, 0);
        setTimeout(function(){
          h.apply(scope, args);
        }, o.delay || 10);
    };
  };


Tags: Ext Event  

类别: Ext |  评论(19) |  浏览(6051) |  收藏
一共有 19 条评论
19楼 [匿名]0yzordrr 2009年11月02日 16:21:20 Says:
%E6%AC%A7%E6%B4%B2%E7%89%B9%E4%BB%B7%E6%9C%BA%E7%A5%A8%E6%8E%A8%E5%87%BA%EF%BC%9A%E9%9B%85%E5%85%B8%20%E4%BC%AF%E6%98%8E%E7%BF%B0%20%E6%9D%9C%E5%A1%9E%E5%B0%94%E5%A4%9A%E5%A4%AB%20%E6%B3%95%E5%85%B0%E5%85%8B%E7%A6%8F%20%E6%A0%BC%E6%8B%89%E6%96%AF%E5%93%A5%20%E6%9B%BC%E5%BD%BB%E6%96%AF%E7%89%B9%20%E4%BC%A6%E6%95%A6%20%E6%B1%89%E5%A0%A1%20%E7%B1%B3%E5%85%B0%20%20%E8%8E%AB%E6%96%AF%E7%A7%91%20%E6%85%95%E5%B0%BC%E9%BB%91%20%20%E5%B7%B4%E9%BB%8E%20%E7%BA%BD%E5%8D%A1%E6%96%AF%E5%B0%94%20%20%E5%B0%BC%E6%96%AF%20%E7%BD%97%E9%A9%AC%20%E5%A8%81%E5%B0%BC%E6%96%AF%20%E7%BB%B4%E4%B9%9F%E7%BA%B3%20%E8%8B%8F%E9%BB%8E%E4%B8%96%20%0D%0A%20%0D%0A%E4%BB%A5%E4%B8%8A%E5%9F%8E%E5%B8%82%E7%9A%84%E4%BB%B7%E6%A0%BC%E6%9C%89%E9%98%BF%E8%81%94%E9%85%8B%E8%88%AA%E7%A9%BA%E5%85%AC%E5%8F%B8%E6%89%BF%E8%BF%90:%E5%BE
18楼 [匿名]3u9ku9qj 2009年11月01日 17:46:16 Says:
%EF%BC%86%E7%89%B9%E4%BB%B7|%E5%8C%97%E4%BA%AC%E5%88%B0%E5%8A%A0%E6%8B%BF%E5%A4%A7%E6%B8%A9%E5%93%A5%E5%8D%8E%E7%89%B9%E4%BB%B7%E5%9B%BD%E9%99%85%E6%9C%BA%E7%A5%A8|%E5%A5%A5%E8%BF%90%E6%9C%BA%E7%A5%A8%20|%E5%9B%A2%E9%98%9F%E6%9B%B4%E4%BC%98%E6%83%A0%20%0D%0A%E5%8D%95%E7%A8%8B%E4%BB%B7%E6%A0%BC%EF%BC%9A3400%E5%85%83%20%20%20%E5%BE
17楼 [匿名]nyg4kdiw 2009年10月24日 06:56:08 Says:
%E4%BE%9B%E5%BA%9407%E5%B9%B4%E4%BA%8C%E6%89%8B%E4%B9%85%E4%BF%9D%E7%94%B0sr75%E6%94%B6%E5%89%B2%E6%9C%BA%E5%A3%B9%E5%8F%B0%EF%BC%8C%E6%B6%A1%E8%BD%AE%E5%A2%9E%E5%8E%8B75%E9%A9%AC%E5%8A%9B%EF%BC%8C%E5%8E%9F%E8%A3%85%E9%A9%BE%E9%A9%B6%E5%AE%A4%EF%BC%8C%E5%B8%A6%E7%A9%BA%E8%B0%83%EF%BC%8C%E6%AF%8F%E5%B0%8F%E6%97%B6%E6%94%B6%E5%89%B2%E6%B0%B4%E7%A8%BB10%E5%88%B015%E4%BA%A9%EF%BC%8C%E6%98%AF%E5%86%9C%E5%9C%BA%E7%A8%BB%E9%BA%A6%E6%94%B6%E5%89%B2%E4%BD%9C%E4%B8%9A%E7%9A%84%E5%BE%97%E5%8A%9B%E5%8A%A9%E6%89%8B%E3
16楼 [匿名]9dpyonk1 2009年10月23日 02:19:26 Says:
%E5%A4%8D%E5%8D%B0%E6%9C%BA%E6%89%93%E5%8D%B0%E6%9C%BA%E7%A2%B3%E7%B2%89%E9%9B%B6%E5%94%AE9%E5%85%83/%E6%96%A4%E8%B5%B7%EF%BC%81%0D%0A%E6%B0%B8%E8%BF%9C%E4%B8%8D%E8%B5%9A%E9%BB%91%E5%BF%83%E9%92%B1%EF%BC%8C%E5%8F%AA%E8%B5%9A%E5%90%88%E7%90%86%E5%88%A9%E6%B6%A6!%0D%0A%E5%A1%91%E6%96%99%E9%99%A4%E9%BB%84%E5%89%82,%E6%84%9F%E5%85%89%E9%BC%93%E4%BF%AE%E5%A4%8D%E6%B6%B2%E6
15楼 [匿名]jtpgnet 2009年10月15日 13:23:10 Says:
%E4%BD%B3%E7%89%B9%E7%9A%AE%E9%9D%A9%E6%8A%A4%E7%90%86%E6%9C%89%E9%99%90%E5%85%AC%E5%8F%B8%E6%8F%90%E4%BE%9B%E5%A4%9A%E7%A7%8D%E6%B4%97%E9%9E%8B%E6%9C%BA%E5%99%A8%E3
14楼 [匿名]9izwot5q 2009年06月19日 09:50:23 Says:
%E7%BD%91%E7%AB%99%E6%8E%A8%E5%B9%BF%E8%BD%AF%E4%BB%B6,%E5%8D%9A%E5%AE%A2%E7%BE%A4%E5%8F%91%E8%BD%AF%E4%BB%B6,%E5%8D%9A%E5%AE%A2%E7%BE%A4%E5%BB%BA%E8%BD%AF%E4%BB%B6,%E7%BD%91%E7%BB%9C%E8%90%A5%E9%94
13楼 [匿名]wv1124 2009年04月29日 21:10:41 Says:
我没有办法处理监听到Ext.Panel的show事件,也监听不到render等非浏览器事件,这是为什么呢,请高手帮解答一下,谢谢了!
12楼 [匿名]的 2009年02月26日 12:32:30 Says:
没看太明白,EXT封装应该是比较隐秘的!!
11楼 [匿名]hehe 2008年10月17日 10:42:24 Says:
学习
10楼 [匿名]cfive 2008年07月26日 10:31:57 Says:
Ext util.Event 中的 name 似乎没有起到什么作用...
9楼 [匿名]cfive 2008年07月26日 10:30:35 Says:
如果不进行任何的封装,你的事件只能唯一的绑定到一个事件处理句柄
...这个说的有些过了吧...

ie 中可以使用 attachEvent
ff 中可以使用 addListener

Ext中实现的事件机制,完全是为了在组件中构造一个自己的事件系统,仅管最后也还是直接或间接的挂钩到 DOM 中的事件去...
8楼 [匿名]gis programmer 2008年07月03日 13:01:46 Says:
在Ext.util.Event在Observable.js中定义!
7楼 [匿名]clint 2008年06月25日 15:08:09 Says:
高手,这几篇文章非常好!
6楼 [匿名]yihj 2008年04月26日 15:54:52 Says:
我也没找到~~,不晓得在哪里找到的?
5楼 程序员 2008年04月25日 08:32:32 Says:
找到了
终于找到了 呵呵
4楼 程序员 2008年04月24日 18:07:34 Says:
真的是找不到啊
新手求教
3楼 程序员 2008年04月24日 18:06:41 Says:
在Ext2.0 API中找不到Ext.Event啊
2楼 [匿名]85732062 2008年03月26日 13:58:27 Says:
在Ext2.0 API中找不到Ext.Event啊
1楼 [匿名]xfan1982 2008年03月23日 09:13:42 Says:
楼主是个高手,这几篇文章非常好!
发表评论
看不清楚,换一张