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操纵Cookie实现购物车程序
Feb 15 Javascript
javascript AOP 实现ajax回调函数使用比较方便
Nov 20 Javascript
基于JS实现的倒计时程序实例
Jul 24 Javascript
Avalon中文长字符截取、关键字符隐藏、自定义过滤器
May 18 Javascript
JavaScript 节流函数 Throttle 详解
Jul 04 Javascript
概述jQuery的元素筛选
Nov 23 Javascript
jQuery ajax调用webservice注意事项
Oct 08 jQuery
教你用Cordova打包Vue项目的方法
Oct 17 Javascript
JavaScript原型链与继承操作实例总结
Aug 24 Javascript
微信小程序日历/日期选择插件使用方法详解
Dec 28 Javascript
JS实现盒子跟着鼠标移动及键盘方向键控制盒子移动效果示例
Jan 29 Javascript
vue和better-scroll实现列表左右联动效果详解
Apr 29 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 Date/Time 类型
2008/03/26 PHP
php获取、检查类名、函数名、方法名的函数方法
2015/06/25 PHP
php中json_encode不兼容JSON_UNESCAPED_UNICODE的解决方案
2016/05/31 PHP
使用PHPExcel导出Excel表
2018/09/08 PHP
JavaScript 对象模型 执行模型
2010/10/15 Javascript
document.documentElement的一些使用技巧
2013/04/18 Javascript
jqGrid随窗口大小变化自适应大小的示例代码
2013/12/28 Javascript
JavaScript中判断整字类型最简洁的实现方法
2014/11/08 Javascript
JQuery控制radio选中和不选中方法总结
2015/04/15 Javascript
Javascript刷新窗口方法小结
2015/10/21 Javascript
JavaScript+CSS无限极分类效果完整实现方法
2015/12/22 Javascript
jquery实现图片预加载
2015/12/25 Javascript
jQuery如何获取动态添加的元素
2016/06/24 Javascript
JavaScript给每一个li节点绑定点击事件的实现方法
2016/12/01 Javascript
解决element-ui中下拉菜单子选项click事件不触发的问题
2018/08/22 Javascript
JS自定义滚动条效果
2020/03/13 Javascript
[01:14:05]《加油DOTA》第四期
2014/08/25 DOTA
[01:27]DOTA2电竞之夜 今夜共饮庆功酒
2014/08/02 DOTA
[00:12]2018DOTA2亚洲邀请赛 sylar表现SOLO技艺
2018/04/06 DOTA
[58:11]守擂赛第二周擂主赛 DeMonsTer vs Leopard
2020/04/28 DOTA
python错误处理详解
2014/09/28 Python
python统计文本字符串里单词出现频率的方法
2015/05/26 Python
Python实现井字棋小游戏
2020/03/09 Python
python实现密码验证合格程序的思路详解
2020/06/01 Python
Django用户认证系统如何实现自定义
2020/11/12 Python
解决import tensorflow导致jupyter内核死亡的问题
2021/02/06 Python
app内嵌H5 webview 本地缓存问题的解决
2020/10/19 HTML / CSS
美国在线鲜花速递:ProFlowers
2017/01/05 全球购物
Mio Skincare英国官网:身体紧致及孕期身体护理
2018/08/19 全球购物
设计4个线程,其中两个线程每次对j增加1,另外两个线程对j每次减少1。写出程序。
2014/12/30 面试题
电气个人求职信范文
2014/02/04 职场文书
公司领导班子对照检查存在问题整改措施
2014/10/02 职场文书
关于感谢信的范文
2015/01/23 职场文书
一次SQL如何查重及去重的实战记录
2022/03/13 MySQL
MySQL普通表如何转换成分区表
2022/05/30 MySQL
win10系统计算机图标怎么调出来?win10调出计算机图标的方法
2022/08/14 数码科技