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获取当前页面路径示例讲解
Jan 08 Javascript
JS实现根据出生年月计算年龄
Jan 10 Javascript
jQuery focus和blur事件的应用详解
Jan 26 Javascript
jQuery.parseJSON(json)将JSON字符串转换成js对象
Jul 27 Javascript
在AngularJS中使用AJAX的方法
Jun 17 Javascript
ES6所改良的javascript“缺陷”问题
Aug 23 Javascript
Bootstrap基本布局实现方法详解
Nov 25 Javascript
JQuery form表单提交前验证单选框是否选中、删除记录时验证经验总结(整理)
Jun 09 jQuery
微信小程序 input表单与redio及下拉列表的使用实例
Sep 20 Javascript
vue-router项目实战总结篇
Feb 11 Javascript
在小程序中使用canvas的方法示例
Sep 17 Javascript
vue开发chrome插件,实现获取界面数据和保存到数据库功能
Dec 01 Vue.js
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截取中文字符串的问题
2006/07/12 PHP
phpmyadmin显示utf8_general_ci中文乱码的问题终级篇
2013/04/08 PHP
ThinkPHP5.0框架控制器继承基类和自定义类示例
2018/05/25 PHP
PHP关于foreach复制知识点总结
2019/01/28 PHP
PHP filter_var() 函数, 验证判断EMAIL,URL等
2021/03/09 PHP
学习ExtJS Panel常用方法
2009/10/07 Javascript
JavaScript 一行代码,轻松搞定浮动快捷留言-V2升级版
2010/04/02 Javascript
关于jquery input textare 事件绑定及用法学习
2013/04/03 Javascript
JavaScript中for-in遍历方式示例介绍
2014/02/11 Javascript
jQuery获取动态生成的元素示例
2014/06/15 Javascript
NodeJS制作爬虫全过程
2014/12/22 NodeJs
JS组件Bootstrap Select2使用方法解析
2016/05/30 Javascript
使用vue-router完成简单导航功能【推荐】
2018/06/28 Javascript
JavaScript实现图片懒加载的方法分析
2018/07/05 Javascript
详解angular应用容器化部署
2018/08/14 Javascript
图文讲解用vue-cli脚手架创建vue项目步骤
2019/02/12 Javascript
js实现跳一跳小游戏
2020/07/31 Javascript
[03:49]辉夜杯现场龙骑士COSER秀情商“我喜欢芬队!”
2015/12/27 DOTA
[04:03][TI9趣味短片] 小鸽子茶话会
2019/08/20 DOTA
[01:33:25]DOTA2-DPC中国联赛 正赛 Elephant vs IG BO3 第一场 1月24日
2021/03/11 DOTA
python写的ARP攻击代码实例
2014/06/04 Python
Python字符串和文件操作常用函数分析
2015/04/08 Python
浅析Python中MySQLdb的事务处理功能
2016/09/21 Python
Python 性能优化技巧总结
2016/11/01 Python
python开发利器之ulipad的使用实践
2017/03/16 Python
详解用TensorFlow实现逻辑回归算法
2018/05/02 Python
Python中使用logging和traceback模块记录日志和跟踪异常
2019/04/09 Python
python bluetooth蓝牙信息获取蓝牙设备类型的方法
2019/11/29 Python
python list等分并从等分的子集中随机选取一个数
2020/11/16 Python
市三好学生主要事迹
2014/01/28 职场文书
感恩节红领巾广播稿
2014/02/11 职场文书
广告宣传策划方案
2014/05/21 职场文书
英文升职感谢信
2015/01/23 职场文书
齐云山导游词
2015/02/06 职场文书
Python数据结构之队列详解
2022/03/21 Python
MySQL数据库之内置函数和自定义函数 function
2022/06/16 MySQL