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 相关文章推荐
一个用js实现控制台控件的代码
Sep 04 Javascript
IE6下出现JavaScript未结束的字符串常量错误的解决方法
Nov 21 Javascript
利用javascript的面向对象的特性实现限制试用期
Aug 04 Javascript
原生javascript实现图片弹窗交互效果
Jan 12 Javascript
gameboy网页闯关游戏(riddle webgame)--仿微信聊天的前端页面设计和难点
Feb 21 Javascript
使用Javascript判断浏览器终端设备(PC、IOS(iphone)、Android)
Jan 04 Javascript
原生JS+Canvas实现五子棋游戏实例
Jun 19 Javascript
对vue里函数的调用顺序介绍
Mar 17 Javascript
Vue中使用create-keyframe-animation与动画钩子完成复杂动画
Apr 09 Javascript
Vue使用lodop实现打印小结
Jul 06 Javascript
javascript sort()对数组中的元素进行排序详解
Oct 13 Javascript
vue 实现购物车总价计算
Nov 06 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
PHP_MySQL教程-第一天
2007/03/18 PHP
php excel类 phpExcel使用方法介绍
2010/08/21 PHP
服务器迁移php版本不同可能诱发的问题
2015/12/22 PHP
在IE中调用javascript打开Excel的代码(downmoon原作)
2007/04/02 Javascript
JavaScript 动态改变图片大小
2009/06/11 Javascript
基于jquery的一个OutlookBar类,动态创建导航条
2010/11/19 Javascript
contains和compareDocumentPosition 方法来确定是否HTML节点间的关系
2011/09/13 Javascript
兼容IE、FireFox、Chrome等浏览器的xml处理函数js代码
2011/11/30 Javascript
JavaScript中的包装对象介绍
2015/01/27 Javascript
js获取新浪天气接口的实现代码
2016/06/06 Javascript
javascript监听页面刷新和页面关闭事件方法详解
2017/01/09 Javascript
原生js实现弹出层效果
2017/01/20 Javascript
浅谈js中function的参数默认值
2017/02/20 Javascript
深入理解Angular.JS中的Scope继承
2017/06/04 Javascript
JS 判断某变量是否为某数组中的一个值的3种方法(总结)
2017/07/10 Javascript
Nodejs下使用gm圆形裁剪并合成图片的示例
2018/02/22 NodeJs
React 组件转 Vue 组件的命令写法
2018/02/28 Javascript
vuejs实现标签选项卡动态更改css样式的方法
2018/05/31 Javascript
js实现指定时间倒计时效果
2019/08/26 Javascript
微信小程序3D轮播实现代码
2019/09/19 Javascript
JavaScript实现手风琴效果
2021/02/18 Javascript
在Django中创建第一个静态视图
2015/07/15 Python
python Shapely使用指南详解
2020/02/18 Python
基于opencv的selenium滑动验证码的实现
2020/07/24 Python
从零实现一个自定义html5播放器的示例代码
2017/08/01 HTML / CSS
CK加拿大官网:Calvin Klein加拿大
2020/03/14 全球购物
英国哈罗德园艺:Harrod Horticultural
2020/03/31 全球购物
数据库面试要点基本概念
2013/10/31 面试题
运动会口号16字
2014/06/07 职场文书
询价采购方案
2014/06/09 职场文书
新闻报道策划方案
2014/06/11 职场文书
启动仪式策划方案
2014/06/14 职场文书
弘扬焦裕禄精神走群众路线思想汇报
2014/09/12 职场文书
倡议书格式及范文
2015/04/29 职场文书
居委会工作总结2015
2015/05/18 职场文书
安全生产学习心得体会
2016/01/18 职场文书