论坛首页 编程语言技术论坛

inEdit 的设计方法--inQueue

浏览 1394 次
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
作者 正文
   发表时间:2008-11-12   最后修改:2008-11-13
C

在inEdit包里面有一个inCore.js的文件,这个文件的对象是inEdit的基础.

在这里面设计的几个对象里面inQueue队列处理对象是比较特殊的一个.

 

inQueue :对序列化函数调用的处理(由于目前仅有Event有实例可讲,所以我只能说这个了)

 

inQueue认为DOM事件的处理也属于队列,不管是一个Element上绑定了多个事件,还是绑定了同一个事件的不同函数调用,又或是冒泡到父级节点Element的事件处理,都是一个函数调用的队列,因此完全可以把这些封装起来管理.而且管理后因为所有相关的Element和函数都被保存起来,更有利调试和处理.

inQueue是这样封装 的:对Element D 增加事件 T
响应 函数 F,就好象这样的代码

 

var D=document.getElementById('id');
var T='onclick';
var F=function(ev){alert('onclick Event')};
D.attachEvent(T, F)

这是一个很常见的代码,这个代码中有几点不方便的地方

  1. 函数F被调用的时候不能指定this.如果F是某个对象obj的成员,希望F被触发的时候可以保持this为obj就更好了.
  2. 不能向F传递附加的参数,这个你说可以用特定的一个变量附加在某个对象上,不错方法正确,inQueue也是这样做,而且让他更合理
  3. event的兼容性问题,我们知道,上面的代码是IE下的代码,Firefox下就要用addEventListener,类似这样的问题还很多,要尽可能的把这些ev进行兼容性处理,来保证被调用的函数不再为此操心

inQueue正是要解决这些问题.inQueue把上面3项

  1. D,在inQueue里称为域   domain
  2. T,在inQueue里称为类型 type
  3. F,在inQueue里还是 fun

还包括this的设置,以及要传递给fun的参数都保存起来,然后从新设定事件触发的函数到inQueue生成的一个函数里,在这个函数里可以访问被保留的这5项参数,根据参数对原始目的的fun进行调用 ,从而完善前面说的不便 .


inQueue的API:

  1. findQueue(domain,type,returnindex)
    查找一个一个队列是否存在,一般用不到
  2. addQueue(withthis,domain,fn,type)
    添加单个队列,一般用不到
  3. removeQueue(domain,type)
    删除一个或全部队列
  4. fireQueue(withthis,domain,type,e)
    触发/传递Event事件,一般用不到
  5. addCmd(cmd,fn)
    为对象自己增加this域命令队列,我自己都不知道什么情况下用,仅仅是理论上的
  6. fireCmd(cmd)
    触发一个队列命令,如果附加了参数那么会覆盖 addCmd 中的附加参数,我自己都不知道什么情况下用
  7. addEvent (withthis,elem,type,fn)
    添加 DOMElement 事件,这个是最实用的了,重点就说他了.
  8. fireEvent(withthis,e,elem)
    模拟或者转发某一个 DOMElement 的事件,我自己都不知道什么情况下用,仅仅是理论上的

API不多(源代码里的注释有些是多余的,因为改了好几次,有些注释是历史遗留的,回头再清理),这里重点介绍的就是addEvent了直接代码说话吧 ,注意autoRemoveQueue的用法

/* 一般情况下不应该直接对inQueue进行操作,应该先生成一个新的对象
 * 当然直接用inQueue对象也可以
 * {autoRemoveQueue:true}是告诉inQueue,当页面关闭,或刷新时自动的删除所有的事件
 */

var myQueue=inMixin({autoRemoveQueue:true},inQueue);
var myobj={
  evclick:function(ev,arg1,arg2){alert('evclick:'+arg1+arg2)}
}
myQueue.addEvent(myobj,document.body,'click',myobj.evclick,'附加参数1','附加参数2');

如何终止队列 或者是终止冒泡 事件

inQueue根据原始事件的返回值和ev的cancelBubble属性进行判断,比如继续按上面的代码

var myobj={
  //这将终止队列但是冒泡会继续
  evclick1:function(ev,arg1,arg2){alert('evclick:'+arg1+arg2);return false;},
  //这将终止队列并终止冒泡,其实终止冒泡是cancelBubble=true通知了系统终止冒泡的
  evclick2:function(ev,arg1,arg2){alert('evclick:'+arg1+arg2);ev.cancelBubble=true;return false;},
}

 

注:对于理论上的东西,由于没有经过实战,所以代码并不可靠,仅仅是一个想法

   发表时间:2008-11-12  
你还真快,看了你的回答我就过来看了,我是第一个浏览的,呵呵。
0 请登录后投票
   发表时间:2008-11-12  
建议在inQueue中增加事件的随机ID,方便在过程中移除同一对象上绑定的不同事件。
0 请登录后投票
   发表时间:2008-11-12  
longleg 写道

建议在inQueue中增加事件的随机ID,方便在过程中移除同一对象上绑定的不同事件。

事实上inQueue采用的方法更好,你注意这两点:
1.removeQueue(domain,type),如果removeQueue(Element),Element是一个DOM节点了,怎么获取,是通过ID还是什么$('.class [name=xxx]')就是另外一回事了.你在绑定addEvent的时候告诉inQueue domain 了,那你是知道的,删除的时候可以再传回去了.
2.myQueue.removeQueue(),就删除了所有的Event了
通过这两种方法的配合已经足以满足多少需求了,无需随机ID了.
inQueue是开源的,您当然可以自己DIY出您特殊的需求了.
0 请登录后投票
   发表时间:2009-06-12  
和Prototype的Event.observe()的机制很相似!
0 请登录后投票
论坛首页 编程语言技术版

跳转论坛:
Global site tag (gtag.js) - Google Analytics