事件设计概述总结,事件相关设计
活动设计概述
事件机制可以使程序逻辑更加符合现实世界。在JavaScript中,许多对象都有自己的事件。例如,按钮有onclick事件,下拉列表框有onchange事件。这些事件有助于编程。那么,你能为你自己定义的类实现事件机制吗?可以,通过事件机制,可以将类设计成一个独立的模块,通过事件对外沟通,提高了程序的开发效率。本节将详细介绍JavaScript中的事件设计模式以及可能出现的问题。
最简单的事件设计模式
最简单的模式是将类的方法成员定义为事件。这不需要任何特殊的语法,它通常是一个空方法,例如:
函数class1(){
//构造函数
}
class1.prototype={
show:function(){
//实现//show函数
this . on show();//触发onShow事件
},
on:function(){ }//定义事件接口
}
在上面的代码中,定义了一个方法:show(),在这个方法中调用onShow()方法。这个onShow()方法是外部事件接口,它的用法如下:
//创建class1的实例
var obj=new class 1();
//为obj创建onShow事件处理程序
obj.onShow=function(){
警报(“onshow事件”);
}
//调用obj的show方法
obj . show();
可以看出,obj.onShow方法是在类外定义的,在类的内部方法Show()中调用,从而实现了事件机制。
上面的方法很简单,在实际开发中经常用来解决一些简单的事件函数。说起来简单,因为它有以下两个缺点:
?不能给事件处理程序传递参数,因为事件处理程序是在show()内部方法中调用的,不能知道外部的参数;
?每个事件接口只能绑定一个事件处理程序,而内部方法可以使用attachEvent或addEventListener方法绑定多个处理程序。
接下来的两节将重点解决这个问题。
将参数传递给事件处理程序
向事件处理程序传递参数不仅是自定义事件的问题,也是系统内部对象的事件机制的问题。因为事件机制只传递不带任何参数信息的函数名,所以它不能传入参数。例如:
//定义类class1
函数class1(){
//构造函数
}
class1.prototype={
show:function(){
//实现//show函数
this . on show();//触发onShow事件
},
on:function(){ }//定义事件接口
}
//创建class1的实例
var obj=new class 1();
//为obj创建onShow事件处理程序
函数objOnShow(用户名){
alert(hello,用户名);
}
//定义变量用户名
var userName= jack
//在obj的Show事件上绑定
obj.onShow=objOnShow//不能传入变量userName。
//调用obj的show方法
obj . show();
请注意,不能编写上述obj.onShow=objOnShow事件绑定语句来传递用户名变量:
obj.onShow=objOnShow(用户名);
或者:
obj . on show= objOnShow(userName);
前者将objOnShow(用户名)的运行结果赋给obj.onShow,后者将字符串“objOnShow(用户名)”赋给obj.onShow。
要解决这个问题,我们可以反过来想,不是如何传入参数,而是如何构建一个没有参数的事件处理程序。这个程序是根据带参数的事件处理程序创建的,是一个外包。现在自定义一个通用函数来实现这个功能:
//将带参数的函数封装为不带参数的函数
函数createFunction(obj,strFunc){
var args=[];//定义args来存储传递给事件处理程序的参数。
如果(!obj)obj=window;//如果是全局函数,obj=window
//获取传递给事件处理程序的参数
for(var I=2;一.论据长度;I)args . push(arguments[I]);
//用无参数函数封装事件处理程序的调用
返回函数(){
obj[strFunc]。apply(obj,args);//将参数传递给指定的事件处理程序
}
}
这种方法将一个带参数的函数封装成一个不带参数的函数,不仅适用于全局函数,也适用于作为对象方法存在的函数。方法首先接收两个参数:obj和strFunc,obj表示事件处理程序所在的对象;StrFunc表示事件处理程序的名称。此外,程序还使用arguments对象处理第二个参数后的隐式参数,即没有定义形参的参数,并在调用事件处理程序时传入这些参数。例如,事件处理程序是:
someobject . eventhandler=function(_ arg 1,_arg2){
//事件处理代码
}
应该打电话:
createFunction(someObject, eventHandler ,arg1,arg 2);
这将返回一个没有参数的函数,而传入的参数已经包含在返回的函数中。如果是作为事件处理程序的全局函数,实际上就是window对象的方法,所以可以把window对象作为obj参数传递。为了清楚起见,还可以将obj指定为null,createFunction函数会自动将该函数视为全局函数,从而自动将obj赋给window。下面是一个应用示例:
脚本语言=JavaScript 类型=text/javascript
!-
//将带参数的函数封装为不带参数的函数
函数createFunction(obj,strFunc){
var args=[];
如果(!obj)obj=window;
for(var I=2;一.论据长度;I)args . push(arguments[I]);
返回函数(){
obj[strFunc]。apply(obj,args);
}
}
//定义类class1
函数class1(){
//构造函数
}
class1.prototype={
show:function(){
//实现//show函数
this . on show();//触发onShow事件
},
on:function(){ }//定义事件接口
}
//创建class1的实例
var obj=new class 1();
//为obj创建onShow事件处理程序
函数objOnShow(用户名){
alert(hello,用户名);
}
//定义变量用户名
var userName= jack
//在obj的Show事件上绑定
obj.onShow=createFunction(null, objOnShow ,userName);
//调用obj的show方法
obj . show();
//-
/脚本
在这段代码中,变量userName作为参数传递给objOnShow事件处理程序。其实obj.onShow得到的事件处理程序并不是objOnShow,而是createFunction返回的无参数函数。
通过createFunction的封装,可以用一个通用的方案实现参数传递。这不仅适用于用户定义的事件,也适用于系统提供的事件。原理完全一样。
使自定义事件支持多个绑定。
您可以使用attachEvent或addEventListener方法来实现多个事件处理程序的同时绑定,而不会相互冲突。自定义事件如何实现多订阅?这种实现描述如下。要实现多订阅,必须需要一种机制来存储多个绑定的事件处理程序,并在事件发生时同时调用这些事件处理程序。从而达到多订阅的效果,具体实现如下:
脚本语言=JavaScript 类型=text/javascript
!-
//定义类class1
函数class1(){
//构造函数
}
//定义类成员
class1.prototype={
show:function(){
//显示代码
//.
//如果有事件绑定,循环onshow数组触发事件。
如果(this.onshow){
for(var I=0;I this . on show . length;i ){
this . on show[I]();//调用事件处理程序
}
}
},
attachon show:function(_ eHandler){
如果(!this . on show)this . on show=[];//用数组存储绑定的事件处理程序引用
this . on show . push(_ eHandler);
}
}
var obj=new class 1();
//事件处理程序1
函数onShow1(){
警报(1);
}
//事件处理程序2
函数onShow2(){
警戒(2);
}
//绑定两个事件处理程序
obj . attachonshow(on show 1);
obj . attachonshow(on show 2);
//调用show,并触发onshow事件
obj . show();
//-
/脚本
从代码的执行结果中,我们可以看到两个绑定的事件处理程序运行正确。如果您希望用参数绑定事件处理程序,只需添加createFunction方法,这在上一节中有所描述。
这种机制基本上解释了处理多事件处理程序的基本思想,但仍有改进的空间。例如,如果一个类有多个事件,可以定义一个类似于attachEvent的方法,以统一的方式处理事件绑定。如果要在添加事件绑定后删除它,还可以定义一个detachEvent方法来解除绑定。这些实现的基本思想是对数组进行操作。