JavaScript事件设计模式

本文章参考自:《征服Ajax Web 2.0 开发技术详解》为了自己日后查阅并与大家共享。

1. 事件设计概述

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

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

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

Js代码  

  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. 给事件处理程序传递参数

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

Js代码  

  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>

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

Js代码  

  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。最后完成的代码如下:

Js代码  

  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事件设计模式

时间: 2024-11-09 00:38:46

JavaScript事件设计模式的相关文章

Javascript事件设计模式(七)

一:事件设计概述 事件机制可以使程序逻辑更加符合现实世界,在JavaScript中很多对象都有自己的事件,例如按钮就有onclick事件,下拉列表框就有 onchange事件,通过这些事件可以方便编程.那么对于自己定义的类,是否也可以实现事件机制呢?是的,通过事件机制,可以将类设计为独立的模块,通过事件对外通信,提高了程序的开发效率. 二: 最简单的事件设计模式 最简单的一种模式是将一个类的方法成员定义为事件,这不需要任何特殊的语法,通常是一个空方法,例如:function class1(){ 

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

zepto的event 可以结合上一篇JavaScript事件详解-原生事件基础(一)综合考虑源码暂且不表,github里还有中文网站都能下到最新版的zepto.整个event模块不长,274行,我们可以看到,整个event模块,事件绑定核心就是on和off,还有一个trigger用来触发,类观察者模式,可以先看看汤姆大叔的深入理解JavaScript系列(32):设计模式之观察者模式,其余皆为实现的处理函数.首先来个demo: $("#btn").on("click&quo

JavaScript 事件代理

转自:http://www.cnblogs.com/silence516/archive/2009/09/03/delegateEvent.html 如果你想给网页添加点JavaScript的交互性,也许你已经听过JavaScript的事件代理(event delegation),并且觉得这是那些发烧友级别的JavaScript程序员才会关心的什么费解的设计模式之一.事实上,如果你已经知道怎么添加JavaScript的事件处理器(event handler),实现事件代理也是件轻而易举的事情.

javascript事件委托机制详解

以个人前端工作面试经历来看,javascript事件委托是问的最多的一类题目之一,熟悉事件委托能够了解你对于javascript的掌握程度. 面试官可能问一下问题,现在有5个li待办事件,需要实现当点击一个li时实现弹出该li的信息 <ul class="top"> <li>橘子</li> <li>香蕉</li> <li>苹果</li> <li>梨子</li> <li>

JavaScript事件委托的技术原理

如今的JavaScript技术界里最火热的一项技术应该是‘事件委托(event delegation)’了.使用事件委托技术能让你避免对特定的每个节点添加事件监听器:相反,事件监听器是被添加到它们的父元素上.事件监听器会分析从子元素冒泡上来的事件,找到是哪个子元素的事件.基本概念非常简单,但仍有很多人不理解事件委托的工作原理.这里我将要解释事件委托是如何工作的,并提供几个纯JavaScript的基本事件委托的例子. 假定我们有一个UL元素,它有几个子元素: <ul id="parent-l

JavaScript事件机制

<script type="text/javascript" src="http://runjs.cn/gist/2zmltkfa/all"></script> [前端培养-作业01]javascript事件机制 1.javascript事件模型 2.e.target与e.currentTarget是干什么的? 3.preventDefault与stopPropagation是干什么的 4.什么是dispatchEvent? 5.说一说事件代

javascript事件委托练习

JavaScript事件代理是一种简单的技巧,通过它你可以把事件处理器添加到一个父级元素上,这样就不需要为每一个元素添加或者删除事件处理器,从而避免了内存泄露或者是遍历节点造成的性能下降. 如果整个页面都采用同样事件流方式,当红色蓝色区域触发相同事件,冒泡法:先处理蓝色区域请求,捕获法:先处理红色区域请求 如果不同层的元素使用的useCapture不同,会先从最外层元素往目标元素寻找设定为capture(捕获)模式的事件,到达目标元素执行目标元素的事件后,再寻原路往外寻找设定为bubbling(

JavaScript事件---事件对象

原文:JavaScript事件---事件对象 发文不易,若转载传播,请亲注明出处,谢谢!   内容提纲: 1.事件对象 2.鼠标事件 3.键盘事件 4.W3C与IE JavaScript事件的一个重要方面是它们拥有一些相对一致的特点,可以给你的开发提供更多的强大功能.最方便和强大的就是事件对象,他们可以帮你处理鼠标事件和键盘敲击方面的情况,此外还可以修改一般事件的捕获/冒泡流的函数. 一.事件对象 事件处理函数的一个标准特性是,以某些方式访问的事件对象包含有关于当前事件的上下文信息. 事件处理三

JavaScript事件代理入门

事件代理(Event Delegation),又称之为事件委托.是 JavaScript 中常用绑定事件的常用技巧. 顾名思义,"事件代理"即是把原本需要绑定的事件委托给父元素,让父元素担当事件监听的职务. 为什么要这样做呢? 众所周知,DOM操作是十分消耗性能的.所以重复的事件绑定简直是性能杀手.而事件代理的核心思想,就是通过尽量少的绑定,去监听尽量多的事件. 下面将会用 Zepto 为大家演示怎么实现事件代理. 啊?Zepto是什么? Zepto is a minimalist J