http://plkong.iteye.com/blog/213543

1. 事件设计概述

事件机制可以是程序逻辑更加清晰可见,在JavaScript中很多对象都有自己的事件,如:button有onclick事件,selcet有onchange事件。对于我们自己设计的类,是否也可以有事件机制呢?答案是肯定的。我们可以通过事件机制,将类设计为独立的模块,从而使其可以通过事件与外通信,提高程序的开发效率。

2. 不带参数的事件设计模式

最简单的一种模式是将一个类的方法成员定义为事件,可以借助JavaScript的基本语法来实现,通常是一个空的方法。例如:

  1. <script language="javascript" type="text/javascript" >
  2. function User(){
  3. }
  4. User.prototype={
  5. show:function(){
  6. this.onShow();//触发onShow事件
  7. },
  8. onShow:function(){}//定义事件接口
  9. }
  10. var obj = new User();
  11. //创建obj的onShow事件处理程序
  12. obj.onShow = function(){
  13. alert("事件触发了");
  14. }
  15. //调用obj的show方法
  16. obj.show();
  17. </script>

obj.onShow 方法在类的外部被定义,在类的内部方法 show() 中被调用,这就实现了事件机制。

此设计模式应用起来简单,但有其有以下缺点:

  • 不能够给事件处理程序传递参数,原因是我们是在 show() 这个内部方法中调用事件处理程序的,无法知道外部的参数。
  • 每个事件接口只能绑定一个事件处理程序,而内部方法则可以使用 attachEvent 或 addEventListener 方法绑定多个处理程序。

3. 给事件处理程序传递参数

给事件处理程序传递参数不仅是自定义事件中存在的问题,也是系统内部对象的事件机制中存在的问题,因为事件机制仅传递一个函数名称,不带有任何参数信息,所以无法传递参数进去。例如:

  1. <script language="javascript" type="text/javascript" >
  2. function User(){
  3. }
  4. User.prototype={
  5. show:function(){
  6. this.onShow();//触发onShow事件
  7. },
  8. onShow:function(){}//定义事件接口
  9. }
  10. var obj = new User();
  11. //创建obj的onshow事件处理程序
  12. function objOnShow(userName){
  13. alert("hello,"+userName);
  14. }
  15. //定义username变量
  16. var userName = "plkong";
  17. //绑定obj的onshow事件
  18. obj.onShow = objOnShow;//无法将userName这个变量传递进去
  19. obj.show();
  20. </script>

上面的程序是无法传递参数进去的,为了解决这个问题,我们可以从相反的思维方式去考虑问题。不考虑怎么把参数传递进去,而是考虑如何构建一个无需参数的事件处理程序。我们看看先看看下面的函数:

  1. /* 将参数的函数封装为无参数的函数 */
  2. function createFunction(obj, strFunc){
  3. var args = [];//定义args用于存储传递给事件处理程序的参数
  4. if(!obj) obj = window;//如果是全局函数则obj = window;
  5. //得到传递给事件处理程序的参数
  6. for( var i = 2; i<arguments.length; i++)
  7. args.push(arguments[i]);
  8. //用无参函数封装事件处理程序的调用
  9. /*
  10. JavaScript为函数对象定义了两个方法:apply 和 call, 它们的作用都是函数绑定到另外一个对象上运行。
  11. */
  12. return function(){
  13. obj[strFunc].apply(obj, args);//将参数传递给指定的事件处理程序
  14. }
  15. }

该方法将一个有参数的函数封装为一个无参数的函数,不仅对全局函数适用,作为对象方法存在的函数也是适用的。该方法首先接收两个参数:obj 和 strFunc ,obj 表示事件处理程序所在的对象; strFunc 表示事件处理程序的名称。程序中还利用了arguments对象(arguments是传递给函数的隐含参数,arguments对象存储的是实际传递给函数的参数,而且不局限与函数声明所定义的形参列表。关于arguments对象可以参考其他资料)处理第二个参数以后的隐式参数,即未定义为形参的参数,

例如:事件处理程序

someObject.eventHandler = function(_arg1, _arg2){

//事件处理代码

}

应该调用:creatFunction(someObject, "eventHander", arg1, arg2);

这样就返回一个无参数的函数,在返回的函数中已经包括了传递进去的参数。如果是全局函数作为事件处理程序,事实上它是window 对象的一个方法,所以可以传递window对象作为obj参数,为了更清晰一点,也可以指定obj为null, creatFunction函数内部会自动认为该函数是全局函数,从而自动吧obj赋值为window。最后完成的代码如下:

    1. <script language="javascript" type="text/javascript" >
    2. /* 将参数的函数封装为无参数的函数 */
    3. function createFunction(obj, strFunc){
    4. var args = [];//定义args用于存储传递给事件处理程序的参数
    5. if(!obj) obj = window;//如果是全局函数则obj = window;
    6. //得到传递给事件处理程序的参数
    7. for( var i = 2; i<arguments.length; i++)
    8. args.push(arguments[i]);
    9. //用无参函数封装事件处理程序的调用
    10. /*
    11. JavaScript为函数对象定义了两个方法:apply 和 call, 它们的作用都是函数绑定到另外一个对象上运行。
    12. */
    13. return function(){
    14. obj[strFunc].apply(obj, args);//将参数传递给指定的事件处理程序
    15. }
    16. }
    17. /**/
    18. function User(){
    19. }
    20. User.prototype={
    21. show:function(){
    22. this.onShow();//触发onShow事件
    23. },
    24. onShow:function(){}//定义事件接口
    25. }
    26. var obj = new User();
    27. //创建obj的onshow事件处理程序
    28. function objOnShow(userName){
    29. alert("hello,"+userName);
    30. }
    31. //定义username变量
    32. var userName = "plkong";
    33. //绑定obj的onshow事件
    34. //obj.onShow = objOnShow;//无法将userName这个变量传递进去
    35. obj.onShow = createFunction(null, "objOnShow", userName);
    36. obj.show();
    37. </script>

javascript 事件设计模式的更多相关文章

  1. javascript事件设计模式

    JavaScript事件设计模式 http://plkong.iteye.com/blog/213543 http://www.docin.com/p-696665922.html

  2. Javascript事件设计模式(七)

    一:事件设计概述 事件机制可以使程序逻辑更加符合现实世界,在JavaScript中很多对象都有自己的事件,例如按钮就有onclick事件,下拉列表框就有 onchange事件,通过这些事件可以方便编程 ...

  3. JavaScript事件详解-Zepto的事件实现(二)【新增fastclick阅读笔记】

    正文 作者打字速度实在不咋地,源码部分就用图片代替了,都是截图,本文讲解的Zepto版本是1.2.0,在该版本中的event模块与1.1.6基本一致.此文的fastclick理解上在看过博客园各个大神 ...

  4. Javascript事件模型系列(四)我所理解的javascript自定义事件

    被我拖延了将近一个月的javascript事件模型系列终于迎来了第四篇,也是我计划中的最后一篇,说来太惭愧了,本来计划一到两个星期写完的,谁知中间遇到了很多事情,公司的个人的,搞的自己心烦意乱浮躁了一 ...

  5. JavaScript事件详解-zepto的事件实现

    zepto的event 可以结合上一篇JavaScript事件详解-原生事件基础(一)综合考虑源码暂且不表,github里还有中文网站都能下到最新版的zepto.整个event模块不长,274行,我们 ...

  6. 7 种 Javascript 常用设计模式学习笔记

    7 种 Javascript 常用设计模式学习笔记 由于 JS 或者前端的场景限制,并不是 23 种设计模式都常用. 有的是没有使用场景,有的模式使用场景非常少,所以只是列举 7 个常见的模式 本文的 ...

  7. JavaScript 事件代理

    转自:http://www.cnblogs.com/silence516/archive/2009/09/03/delegateEvent.html 如果你想给网页添加点JavaScript的交互性, ...

  8. JavaScript事件代理和委托(Delegation)

    JavaScript事件代理 首先介绍一下JavaScript的事件代理.事件代理在JS世界中一个非常有用也很有趣的功能.当我们需要对很多元素添加事件的时候,可以通过将事件添加到它们的父节点而将事件委 ...

  9. JavaScript事件概览

    JavaScript事件 JavaScript是单线程,在同一个时间点,不可能同时运行两个"控制线程". 事件句柄和事件对象 1.注册事件句柄 标准和非标准 var button= ...

随机推荐

  1. asp.net mvc4 signalR后台自推送

    1.在引用中添加signalr后首选要引入Startup.cs类,在VS2012中添加Signalr后没有Startup.cs类然后就会报错 代码如下 using System; using Syst ...

  2. ubuntu下安装fiddler

    因为工作中需要用到fiddler工具  现在工作环境迁移到ubuntu14 下  发现fiddler只支持windows网上也有很多推荐 号称可以代替fiddler   但因为功能使用上比较习惯  并 ...

  3. 常用两种数据交换格式之XML和JSON的比较

    目前,在web开发领域,主要的数据交换格式有XML和JSON,对于XML相信每一个web developer都不会感到陌生: 相比之下,JSON可能对于一些新步入开发领域的新手会感到有些陌生,也可能你 ...

  4. OC 代理 协议 委托 数据源的概念

    (网摘) OBJC 中的 protocol 相当于 java 里的接口,delagate 就是接口的实现类(C中的回调类似 ): 数据源就是对象遵循了存储数据的协议,可以存储使用数据 协议表示了方法可 ...

  5. ORA-14400: inserted partition key does not map to any partition

    ORA-14400: inserted partition key does not map to any partition 数据库表已经分区,如果插入数据时出现错误提示: ORA-14400: 插 ...

  6. Axure快捷键大全

    基本快捷键: 打开:Ctrl + O 新建:Ctrl + N 保存:Ctrl + S 退出:Alt + F4 打印:Ctrl + P 查找:Ctrl + F 替换:Ctrl + H 复制:Ctrl + ...

  7. 在javascript中使用com组件的方法

    转载自:  http://dhailin.blog.163.com/blog/static/230738322011128102043880/ 首先创建一个COM组件,插入一个双接口Itest,在此接 ...

  8. FVANCOP/ChartNew.js

    FVANCOP/ChartNew.js FVANCOP/ChartNew.js

  9. BorderLayout布局,修改各个区域大小办法

    摘自http://blog.csdn.net/zcsearching/article/details/50808446 BorderLayout控件大小的设置 使用BorderLayout时,中间的面 ...

  10. VBA:Google翻译(含tk算法)

    完整的tk算法: //源自http://translate.google.cn/ TKK=eval('((function(){var a\x3d618632403;var b\x3d14854840 ...