javascript 自定义事件初探


Posted in Javascript onAugust 21, 2009

还有,“通过事件机制,可以将类设计为独立的模块,通过事件对外通信,提高了程序的开发效率。”。相信C#程序员对事件的好处是深有体会的。好了,Code is cheap.看代码:
function class1() { // 最简单的事件设计模式
}
class1.prototype = {
show: function () {
this .onShow();
},
onShow: function () { }
}
function test() {
var obj = new class1();
obj.onShow = function () {
alert( " test " );
}
obj.show();
}
下面看看如何给事件处理程序传递参数:
// 将有参数的函数封装为无参数的函数
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]);
// 用无参数函数封装事件处理程序的调用
return function () {
obj[strFunc].apply(obj, args); // 将参数传递给指定的事件处理程序
}
}
function class1() {
}
class1.prototype = {
show: function () {
this .onShow();
},
onShow: function () { }
}
function objOnShow(userName) {
alert( " hello, " + userName);
}
function test() {
var obj = new class1();
var userName = " test " ;
obj.onShow = createFunction( null , " objOnShow " , userName);
obj.show();
}

"因为事件机制仅传递一个函数的名称,不带有任何参数的信息,所以无法传递参数进去",这是后话了,“要解决这个问题,可以从相反的思路去考虑,不考虑怎么把参数传进去,而是考虑如何构建一个无需参数的事件处理程序,该程序是根据有参数的事件处理程序创建的,是一个外层的封装。”,这里的“该程序”就是 createFunction函数,它巧妙地利用apply函数将带参数的函数封装为无参数函数。最后我们看看如何实现自定义事件的多绑定:
// 使自定义事件支持多绑定
// 将有参数的函数封装为无参数的函数
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]);
// 用无参数函数封装事件处理程序的调用
return function () {
obj[strFunc].apply(obj, args); // 将参数传递给指定的事件处理程序
}
}
function class1() {
}
class1.prototype = {
show: function () {
if ( this .onShow) {
for ( var i = 0 ; i < this .onShow.length; i ++ ) {
this .onShow[i]();
}
}
},
attachOnShow: function (_eHandler) {
if ( ! this .onShow) { this .onShow = []; }
this .onShow.push(_eHandler);
}
}
function objOnShow(userName) {
alert( " hello, " + userName);
}
function objOnShow2(testName) {
alert( " show: " + testName);
}
function test() {
var obj = new class1();
var userName = " your name " ;
obj.attachOnShow(createFunction( null , " objOnShow " , userName));
obj.attachOnShow(createFunction( null , " objOnShow2 " , " test message " ));
obj.show();
}
我们看到,attachOnShow方法实现的基本思想是对数组的push操作,其实我们还可以在事件执行完成之后,移除事件处理函数,下面单独实现:
// 将有参数的函数封装为无参数的函数
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]);
// 用无参数函数封装事件处理程序的调用
return function () {
obj[strFunc].apply(obj, args); // 将参数传递给指定的事件处理程序
}
}
function class1() {
}
class1.prototype = {
show: function () {
if ( this .onShow) {
for ( var i = 0 ; i < this .onShow.length; i ++ ) {
this .onShow[i]();
}
}
},
attachOnShow: function (_eHandler) { // 附加事件
if ( ! this .onShow) { this .onShow = []; }
this .onShow.push(_eHandler);
},
detachOnShow: function (_eHandler) { // 移除事件
if ( ! this .onShow) { this .onShow = []; }
this .onShow.pop(_eHandler);
}
}

function objOnShow(userName) {
alert( " hello, " + userName);
}
function objOnShow2(testName) {
alert( " show: " + testName);
}
function test() {
var obj = new class1();
var userName = " your name " ;
obj.attachOnShow(createFunction( null , " objOnShow " , userName));
obj.attachOnShow(createFunction( null , " objOnShow2 " , " test message " ));
obj.show();
obj.detachOnShow(createFunction( null , " objOnShow " , userName));
obj.show(); // 移除一个,显示剩余的一个
obj.detachOnShow(createFunction( null , " objOnShow2 " , " test message " ));
obj.show(); // 两个都移除,一个也不显示
}
关于自定义事件的学习先到这里。

Javascript 相关文章推荐
清华大学出版的事半功倍系列 javascript全部源代码
May 04 Javascript
javascript使用prototype完成单继承
Dec 24 Javascript
JavaScript修改浏览器tab标题小技巧
Jan 06 Javascript
jQuery中parentsUntil()方法用法实例
Jan 07 Javascript
浅谈JavaScript Math和Number对象
Jan 26 Javascript
javascript内置对象操作详解
Feb 04 Javascript
EasyUI中datagrid在ie下reload失败解决方案
Mar 09 Javascript
JSON创建键值对(key是中文或者数字)方式详解
Aug 24 Javascript
vue组件之Alert的实现代码
Oct 17 Javascript
JavaScript实现微信红包算法及问题解决方法
Apr 26 Javascript
vue自动化路由的实现代码
Sep 30 Javascript
JS实现时间校验的代码
May 25 Javascript
IE 下的只读 innerHTML
Aug 21 #Javascript
JS 控制CSS样式表
Aug 20 #Javascript
JS获取父节点方法
Aug 20 #Javascript
javascript 数组排序函数
Aug 20 #Javascript
用Javascript数组处理多个字符串的连接问题
Aug 20 #Javascript
JQUERY 浏览器判断实现函数
Aug 20 #Javascript
google地图的路线实现代码
Aug 20 #Javascript
You might like
MySQL授权问题总结
2007/05/06 PHP
一个PHP分页类的代码
2011/05/18 PHP
PHP字符串的递增和递减示例介绍
2014/02/11 PHP
PHP Swoole异步Redis客户端实现方法示例
2019/10/24 PHP
根据分辨率不同,调用不同的css文件
2006/07/07 Javascript
javascript中的作用域和上下文使用简要概述
2013/12/05 Javascript
js禁止回车提交表单的示例代码
2013/12/23 Javascript
jQuery常用的一些技巧汇总
2016/03/26 Javascript
极力推荐10个短小实用的JavaScript代码段
2016/08/03 Javascript
jQuery 选择符详细介绍及整理
2016/12/02 Javascript
浅述节点的创建及常见功能的实现
2016/12/15 Javascript
JS完成画圆圈的小球
2017/03/07 Javascript
干货!教大家如何选择Vue和React
2017/03/13 Javascript
nodejs中使用HTTP分块响应和定时器示例代码
2017/03/19 NodeJs
webpack配置打包后图片路径出错的解决
2018/04/26 Javascript
详解使用VueJS开发项目中的兼容问题
2018/08/02 Javascript
React事件处理的机制及原理
2018/12/03 Javascript
基于JavaScript实现留言板功能
2020/03/16 Javascript
vue-cli 关闭热更新操作
2020/09/18 Javascript
[00:57]深扒TI7聊天轮盘语音出处5
2017/05/11 DOTA
跟老齐学Python之dict()的操作方法
2014/09/24 Python
在Python中操作文件之seek()方法的使用教程
2015/05/24 Python
在Python程序和Flask框架中使用SQLAlchemy的教程
2016/06/06 Python
Android 兼容性问题:java.lang.UnsupportedOperationException解决办法
2017/03/19 Python
Python实现获取照片拍摄日期并重命名的方法
2017/09/30 Python
python 实时得到cpu和内存的使用情况方法
2018/06/11 Python
Python计算开方、立方、圆周率,精确到小数点后任意位的方法
2018/07/17 Python
把JSON数据格式转换为Python的类对象方法详解(两种方法)
2019/06/04 Python
python带参数打包exe及调用方式
2019/12/21 Python
pycharm实现print输出保存到txt文件
2020/06/01 Python
写一个在SQL Server创建表的SQL语句
2012/03/10 面试题
千元咖啡店的创业计划书范文
2013/12/29 职场文书
四个太阳教学反思
2014/02/01 职场文书
三好学生演讲稿范文
2014/04/26 职场文书
购房公证委托书(2014版)
2014/09/12 职场文书
python 实现图片特效处理
2022/04/03 Python