javascript 事件设计模式
http://plkong.iteye.com/blog/213543
1. 事件设计概述
事件机制可以是程序逻辑更加清晰可见,在JavaScript中很多对象都有自己的事件,如:button有onclick事件,selcet有onchange事件。对于我们自己设计的类,是否也可以有事件机制呢?答案是肯定的。我们可以通过事件机制,将类设计为独立的模块,从而使其可以通过事件与外通信,提高程序的开发效率。
2. 不带参数的事件设计模式
最简单的一种模式是将一个类的方法成员定义为事件,可以借助JavaScript的基本语法来实现,通常是一个空的方法。例如:
- <script language="javascript" type="text/javascript" >
- function User(){
- }
- User.prototype={
- show:function(){
- this.onShow();//触发onShow事件
- },
- onShow:function(){}//定义事件接口
- }
- var obj = new User();
- //创建obj的onShow事件处理程序
- obj.onShow = function(){
- alert("事件触发了");
- }
- //调用obj的show方法
- obj.show();
- </script>
obj.onShow 方法在类的外部被定义,在类的内部方法 show() 中被调用,这就实现了事件机制。
此设计模式应用起来简单,但有其有以下缺点:
- 不能够给事件处理程序传递参数,原因是我们是在 show() 这个内部方法中调用事件处理程序的,无法知道外部的参数。
- 每个事件接口只能绑定一个事件处理程序,而内部方法则可以使用 attachEvent 或 addEventListener 方法绑定多个处理程序。
3. 给事件处理程序传递参数
给事件处理程序传递参数不仅是自定义事件中存在的问题,也是系统内部对象的事件机制中存在的问题,因为事件机制仅传递一个函数名称,不带有任何参数信息,所以无法传递参数进去。例如:
- <script language="javascript" type="text/javascript" >
- function User(){
- }
- User.prototype={
- show:function(){
- this.onShow();//触发onShow事件
- },
- onShow:function(){}//定义事件接口
- }
- var obj = new User();
- //创建obj的onshow事件处理程序
- function objOnShow(userName){
- alert("hello,"+userName);
- }
- //定义username变量
- var userName = "plkong";
- //绑定obj的onshow事件
- obj.onShow = objOnShow;//无法将userName这个变量传递进去
- obj.show();
- </script>
上面的程序是无法传递参数进去的,为了解决这个问题,我们可以从相反的思维方式去考虑问题。不考虑怎么把参数传递进去,而是考虑如何构建一个无需参数的事件处理程序。我们看看先看看下面的函数:
- /* 将参数的函数封装为无参数的函数 */
- function createFunction(obj, strFunc){
- var args = [];//定义args用于存储传递给事件处理程序的参数
- if(!obj) obj = window;//如果是全局函数则obj = window;
- //得到传递给事件处理程序的参数
- for( var i = 2; i<arguments.length; i++)
- args.push(arguments[i]);
- //用无参函数封装事件处理程序的调用
- /*
- JavaScript为函数对象定义了两个方法:apply 和 call, 它们的作用都是函数绑定到另外一个对象上运行。
- */
- return function(){
- obj[strFunc].apply(obj, args);//将参数传递给指定的事件处理程序
- }
- }
该方法将一个有参数的函数封装为一个无参数的函数,不仅对全局函数适用,作为对象方法存在的函数也是适用的。该方法首先接收两个参数: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。最后完成的代码如下:
- <script language="javascript" type="text/javascript" >
- /* 将参数的函数封装为无参数的函数 */
- function createFunction(obj, strFunc){
- var args = [];//定义args用于存储传递给事件处理程序的参数
- if(!obj) obj = window;//如果是全局函数则obj = window;
- //得到传递给事件处理程序的参数
- for( var i = 2; i<arguments.length; i++)
- args.push(arguments[i]);
- //用无参函数封装事件处理程序的调用
- /*
- JavaScript为函数对象定义了两个方法:apply 和 call, 它们的作用都是函数绑定到另外一个对象上运行。
- */
- return function(){
- obj[strFunc].apply(obj, args);//将参数传递给指定的事件处理程序
- }
- }
- /**/
- function User(){
- }
- User.prototype={
- show:function(){
- this.onShow();//触发onShow事件
- },
- onShow:function(){}//定义事件接口
- }
- var obj = new User();
- //创建obj的onshow事件处理程序
- function objOnShow(userName){
- alert("hello,"+userName);
- }
- //定义username变量
- var userName = "plkong";
- //绑定obj的onshow事件
- //obj.onShow = objOnShow;//无法将userName这个变量传递进去
- obj.onShow = createFunction(null, "objOnShow", userName);
- obj.show();
- </script>
javascript 事件设计模式的更多相关文章
- javascript事件设计模式
JavaScript事件设计模式 http://plkong.iteye.com/blog/213543 http://www.docin.com/p-696665922.html
- Javascript事件设计模式(七)
一:事件设计概述 事件机制可以使程序逻辑更加符合现实世界,在JavaScript中很多对象都有自己的事件,例如按钮就有onclick事件,下拉列表框就有 onchange事件,通过这些事件可以方便编程 ...
- JavaScript事件详解-Zepto的事件实现(二)【新增fastclick阅读笔记】
正文 作者打字速度实在不咋地,源码部分就用图片代替了,都是截图,本文讲解的Zepto版本是1.2.0,在该版本中的event模块与1.1.6基本一致.此文的fastclick理解上在看过博客园各个大神 ...
- Javascript事件模型系列(四)我所理解的javascript自定义事件
被我拖延了将近一个月的javascript事件模型系列终于迎来了第四篇,也是我计划中的最后一篇,说来太惭愧了,本来计划一到两个星期写完的,谁知中间遇到了很多事情,公司的个人的,搞的自己心烦意乱浮躁了一 ...
- JavaScript事件详解-zepto的事件实现
zepto的event 可以结合上一篇JavaScript事件详解-原生事件基础(一)综合考虑源码暂且不表,github里还有中文网站都能下到最新版的zepto.整个event模块不长,274行,我们 ...
- 7 种 Javascript 常用设计模式学习笔记
7 种 Javascript 常用设计模式学习笔记 由于 JS 或者前端的场景限制,并不是 23 种设计模式都常用. 有的是没有使用场景,有的模式使用场景非常少,所以只是列举 7 个常见的模式 本文的 ...
- JavaScript 事件代理
转自:http://www.cnblogs.com/silence516/archive/2009/09/03/delegateEvent.html 如果你想给网页添加点JavaScript的交互性, ...
- JavaScript事件代理和委托(Delegation)
JavaScript事件代理 首先介绍一下JavaScript的事件代理.事件代理在JS世界中一个非常有用也很有趣的功能.当我们需要对很多元素添加事件的时候,可以通过将事件添加到它们的父节点而将事件委 ...
- JavaScript事件概览
JavaScript事件 JavaScript是单线程,在同一个时间点,不可能同时运行两个"控制线程". 事件句柄和事件对象 1.注册事件句柄 标准和非标准 var button= ...
随机推荐
- Google谷歌搜索引擎登录网站 - Blog透视镜
建置好了网站之后,为了能提升流量或是增加曝光度,Mix通常会到Google谷歌,用手动登录的方式,登录网站,不久之后,搜索引擎就会派遣蜘蛛机器人,来检索你的网站,等一段时间之后,就会出现在搜索引擎内, ...
- [转载] 50个Android开发人员必备UI效果源码
好东西,多学习! Android 仿微信之主页面实现篇Android 仿微信之界面导航篇Android 高仿QQ 好友分组列表Android 高仿QQ 界面滑动效果Android 高仿QQ 登陆界面A ...
- C语言预处理命令总结大全
C程序的源代码中可包括各种编译指令,这些指令称为预处理命令.虽然它们实际上不是C语言的一部分,但却扩展了C程序设计的环境.本节将介绍如何应用预处理程序和注释简化程序开发过程,并提高程序的可读性.ANS ...
- linux下mysql数据库的操作
本文主要针对linux下mysql数据库的安装,以及数据库的创建和简单的数据库操作进行说明. ①.Mysql数据库的安装: 数据库的安装分为源码安装和rpm安装. 当然对于老手来说需要进行一些自定义的 ...
- Lake Counting (POJ No.2386)
有一个大小为N*M的园子,雨后积起了水,八连通的积水被认为是链接在一起的求出园子里一共有多少水洼? *** *W* *** /** *进行深度优先搜索,从第一个W开始,将八个方向可以到达的 W修改为 ...
- 遍历父视图上的button
for (UIView * thebtn in [self.view subviews]) { if ([thebtn isKindOfClass:[UIButton class]]) { //*** ...
- ExtJS+ASP.NET自己定义曲线
第一步:创建Store数据源 var myData = []; myData.push({ 'name': '1', 'Oil_Production': '30', 'Water_Injection' ...
- AJAX最简单的原理以及应用
Ajax是创建快速动态网页的技术,通过后台与服务器少量的数据交互,是网页实现异步更新.也就是在不整个刷新页面的情况下,可以更新网页中的局部区域. 在原始web应用的模式中: 浏览器 以 h ...
- C# 零散笔记
关于控件 控件实质就是一个类 属性中的Name就是它实例后的变量名 属性中的其他东西就是类中的变量或函数 例如: 可以直接通过Name.BackColor=Color.Yellow; 来直接操作控件的 ...
- 伪元素::before和::after
有时候我们的页面里面有不少其他网站的名字,而且还要求网站名后面还要有网站的链接,类似这样:百度(http://www.baidu.com).这个时候如果网站多的话写起来就很麻烦了 <a href ...