js自定义事件及事件交互原理概述(二)


Posted in Javascript onFebruary 01, 2013

js自定义事件(一)的目的只是让大家简单的理解自定事件是如何模拟出来的,大家不难发现会有很多缺陷,比如:
1、此事件对象只能注册一个事件,不能提供多个事件
2、注册方法没有返回的一些信息

下面我们就来解决这些问题。如下为MyEvent.js源代码:

function MyEvent(){ 
this.handlers={}; 
} 
MyEvent.prototype={ 
addHandler:function(type,handler) 
{ 
if(typeof this.handlers[type]=="undefined") 
{ 
this.handlers[type]=[]; 
} 
this.handlers[type].push(handler); 
}, 
fire:function(event) 
{if(this.handlers[event.type] instanceof Array) 
{ 
var handlers=this.handlers[event.type]; 
for(var i= 0, len=handlers.length;i<len;i++) 
{ 
handlers[i](event); 
} 
} 
}, 
removeHandler:function(type,handler) 
{ 
if(this.handlers[type] instanceof Array) 
{ 
var handlers=this.handlers[type]; 
for(var i= 0, len=handlers.length;i<len;i++) 
{ 
if(handlers[i]===handler) 
{ 
break; 
} 
} 
handlers.splice(i,1); 
} 
} 
};

此类就是对第一篇的优化。
属性handler变成了handlers,变成了一个数组
addHandler()方法接受两个参数:事件类型和用于处理该事件的函数。当调用该方法时,会进行一次检查,看看handlers属性中是否已经存在一个针对该事件类型的数组
;如果没有,则创建一个新的。然后使用push()将该处理程序添加到数组的末尾。

fire()方法用于触发一个事件,该方法接受一个参数,是一个至少包含type属性的对象,不然无法确定handlers里面是否已经存在。它会通过此type去查找对应该事件类型的一组处理程序,调用各个函数,并给出event对象。因为这些都是自定义对象,所以event对象上面的其他东西可以由你自己定义。

removeHandler()方法时addHandler()的辅助,它们接受的参数一样:事件的类型和事件处理程序。这个方法搜索事件处理程序的数组找到要删除的处理程序的位置。如果找到了,则使用break操作符退出循环。然后使用splice()方法将该项目从数组中删除。

这里使用方式我们换一种比较长用的形式,现在据我说知很多产品在使用事件上有两种方式,一种是直接继承(js本省没有此概念,不过我们可以通过原型链模拟出继承的效果,此处不做详细解释)此事件对象,那么就会拥有了这些行为,不过此方法比较局限,另一种方式更常用一些,就是需要使用事件的类上面创建一个属性用于存放此对象。如:子相同目录下再创建一个Student.js文件,里面的代码如下:

function Student(name) 
{ 
this.myEvent=new MyEvent(); 
this.name=name; 
} 
Student.prototype={ 
setName:function(name) 
{ 
var eventStart={ 
type:"changeNameStart", 
newName:name, 
oldName:this.name 
}; 
this.myEvent.fire(eventStart); 
this.name=name; 
} 
}

这里有一个学生类,构造函数里面初始化一个MyEvent对象作为属性,通过参数初始化name属性。

提供一个方法setName用于改变名字,不过在改变名字之前设置了可能触发事件changNameStart的监听。
创建一个html页面,放于同个目录下,代码如下:

<html> 
<head> 
<title></title> 
<script type="text/javascript" src="MyEvent.js"></script> 
<script type="text/javascript" src="Student.js"></script> 
<script type="text/javascript"> 
function init() 
{ 
 //初始化一个学生对象 
var student=new Student("Mr liu"); 
 //注册事件changNameStart 
student.myEvent.addHandler("changeNameStart",myMethod); 
//设置name,将会触发事件changNameStart 
student.setName("Mr Huang"); 
} 
function myMethod(e) 
{ 
alert("事件类型:"+e.type+"; 改变前的名字:"+ e.oldName+"; 改变后的名字:"+ e.newName); 
} 
</script> 
</head> 
<body> 
<input type="button" onclick="init()" value="测试" /> 
</body> 
</html>

这样使用起来就会很方便,也是一种常用的使用方式。
一般在真正的项目里面使用使用事件时我们还需要做一些优化,比如:
1、用户并不知道我们提供了哪些事件,从代码来看好像什么事件都可以添加到handlers里面,但是真正起效果的(我们设置fire()方法的地方)事件我们并不能从代码里面很直观的看出来,一般做产品,在这方面都需要再做考虑。

2、有没有发现fire的参数event好像没用固定,在大兴项目里面,最好event也做成一个类型,在fire的地方就比较方便使用一些,event可能会有很多种类型,那时可能fire里面会出现一些判定了。
希望对初入js事件的读者有所帮助,互相交流。

Javascript 相关文章推荐
非常漂亮的JS代码经典广告
Oct 21 Javascript
[原创]IE view-source 无法查看看源码 JavaScript看网页源码
Jul 19 Javascript
jquery validate.js表单验证的基本用法入门
May 13 Javascript
Javascript的数组与字典用法与遍历对象的属性技巧
Nov 07 Javascript
浅析Js中的单引号与双引号问题
Nov 06 Javascript
JavaScript基础教程之alert弹出提示框实例
Oct 16 Javascript
js流动式效果显示当前系统时间
May 16 Javascript
利用Javascript裁剪图片并存储的简单实现
Mar 13 Javascript
基于Vue实现tab栏切换内容不断实时刷新数据功能
Apr 13 Javascript
angular2 ng2 @input和@output理解及示例
Oct 10 Javascript
Vue三层嵌套路由的示例代码
May 05 Javascript
Vue仿百度搜索功能
Dec 28 Vue.js
js自定义事件及事件交互原理概述(一)
Feb 01 #Javascript
js解析与序列化json数据(三)json的解析探讨
Feb 01 #Javascript
js解析与序列化json数据(二)序列化探讨
Feb 01 #Javascript
js解析与序列化json数据(一)json.stringify()的基本用法
Feb 01 #Javascript
百度地图api应用标注地理位置信息(js版)
Feb 01 #Javascript
jquery select动态加载选择(兼容各种浏览器)
Feb 01 #Javascript
表单元素的submit()方法和onsubmit事件应用概述
Feb 01 #Javascript
You might like
用php实现让页面只能被百度gogole蜘蛛访问的方法
2009/12/29 PHP
ThinkPHP跳转页success及error模板实例教程
2014/07/17 PHP
第一个JavaScript入门基础 document.write输出
2010/02/22 Javascript
jQuery效果 slideToggle() 方法(在隐藏和显示之间切换)
2011/06/28 Javascript
JQuyer $.post 与 $.ajax 访问WCF ajax service 时的问题需要注意的地方
2011/09/20 Javascript
Javasipt:操作radio标签详解
2013/12/30 Javascript
JavaScript中将数组进行合并的基本方法讲解
2016/03/07 Javascript
仅一个form表单 js实现注册信息依次填写提交功能
2016/06/12 Javascript
利用JavaScript阻止表单提交的两种方法
2016/08/11 Javascript
vue2.0父子组件间通信的实现方法
2017/04/19 Javascript
JavaScript实现异步图像上传功能
2018/07/12 Javascript
pm2发布node配置文件ecosystem.json详解
2019/05/15 Javascript
el-table树形表格表单验证(列表生成序号)
2020/05/31 Javascript
微信小程序整个页面的自动适应布局的实现
2020/07/12 Javascript
[34:47]完美世界DOTA2联赛PWL S2 Magma vs LBZS 第一场 11.18
2020/11/18 DOTA
Python中MYSQLdb出现乱码的解决方法
2014/10/11 Python
用python找出那些被“标记”的照片
2017/04/20 Python
python+matplotlib实现鼠标移动三角形高亮及索引显示
2018/01/15 Python
Python RabbitMQ消息队列实现rpc
2018/05/30 Python
Python定义函数功能与用法实例详解
2019/04/08 Python
python梯度下降算法的实现
2020/02/24 Python
python画图常规设置方式
2020/03/05 Python
Django之全局使用request.user.username的实例详解
2020/05/14 Python
python3.6.8 + pycharm + PyQt5 环境搭建的图文教程
2020/06/11 Python
python利用xlsxwriter模块 操作 Excel
2020/10/14 Python
css3中background新增的4个新的相关属性用法介绍
2013/09/26 HTML / CSS
KIKO MILANO英国官网:意大利知名化妆品和护肤品品牌
2017/09/25 全球购物
Elemis美国官网:英国的第一豪华护肤品牌
2018/03/15 全球购物
新加坡一家在线男士皮具品牌:Faire Leather Co.
2019/12/01 全球购物
俄罗斯皮肤健康中心:Pharmacosmetica.ru
2020/02/22 全球购物
设备收款委托书范本
2014/10/02 职场文书
债务授权委托书范本
2014/10/17 职场文书
学生党员检讨书范文
2014/12/27 职场文书
2015年教师师德师风承诺书
2015/04/28 职场文书
开业庆典致辞
2015/08/01 职场文书
pandas提升计算效率的一些方法汇总
2021/05/30 Python