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. mysql-protocol中对编码长度整数型的规则

    固定长度整型数值在mysql 协议中的应用之一就是affected row :这个要根据首字节来判断 1.如果首字节小于251;那么首字节就是它要表示的数值. 2.如果首字节等于251;那么它表示的就 ...

  2. css3的loadding效果

    <!DOCTYPE html> <html> <head> <title>CSS3 loading效果</title> <meta c ...

  3. [Errno 11004] getaddrinfo failed

    该程序是在用python发送邮件的时候出现的 出现这个错误的时候,证明连不上你的帐号,或者登录不上服务器~超时连接 检查下自己的帐号或者服务器的编写有没有正确

  4. 在WPF中使用ArcGIS Engine

    原文 http://blog.csdn.net/zzahkj/article/details/9102621 1.首先,新建一个WPF项目,添加引用ESRI.ArcGIS.AxControls.ESR ...

  5. SQL数据转移

    方法一:如果想把数据库A中的表Table1中的数据复制到数据库B中的表Table2中,也就是要预先建立Table2,可以使用一下语句: use B goinsert into Table2 selec ...

  6. Unique Binary Search Trees II 解答

    Question Given n, generate all structurally unique BST's (binary search trees) that store values 1.. ...

  7. UIView 弹出动画

    // 展开动画 - (void)beginAnimations { CGContextRef context = UIGraphicsGetCurrentContext(); [UIView begi ...

  8. spark-submit

    一旦用户的应用打包后,就可以使用bin/spark-submit脚本来启动,此脚本就会为Spark和它的依赖安排配置环境变量,还支持不同的集群管理和部署模式: ./bin/spark-submit \ ...

  9. qsort的几种用法

    #include<stdio.h> #include<stdlib.h> int cmp(const void *a,const void *b){ return *(int ...

  10. react-native 环境配置及hello world

    一.前言 最近手头的工作繁多,有研究性的项目和系统研发,正好遇到同事离职,接手了框架的UI组件,不仅需要维护和填坑,还需要开发新的功能组件.因为身在H5-Hybird的框架部门,最近团队开始尝试使用R ...