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 禁止选择功能实现代码(兼容IE/Firefox)
Apr 23 Javascript
JSON语法五大要素图文介绍
Dec 04 Javascript
jquery简单的拖动效果实现原理及示例
Jul 26 Javascript
实现无刷新联动例子汇总
May 20 Javascript
浅述Javascript的外部对象
Dec 07 Javascript
详解用Node.js实现Restful风格webservice
Sep 29 Javascript
原生JS实现网页手机音乐播放器 歌词同步播放的示例
Feb 02 Javascript
在Vant的基础上实现添加表单验证框架的方法示例
Dec 05 Javascript
微信小程序实现购物页面左右联动
Feb 15 Javascript
微信小程序缓存支持二次开发封装实现解析
Dec 16 Javascript
JS实现放大镜效果
Sep 21 Javascript
浅谈react useEffect闭包的坑
Jun 08 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实现图片裁剪、添加水印效果代码
2014/10/01 PHP
PHP实现动态web服务器方法
2015/07/29 PHP
Js callBack 返回前一页的js方法
2008/11/30 Javascript
javascript iframe中打开文件,并检测iframe存在否
2008/12/28 Javascript
Jquery优化效率 提升性能解决方案
2010/09/06 Javascript
JS获取月的最后一天与JS得到一个月份最大天数的实例代码
2013/12/16 Javascript
js库Modernizr的介绍和使用
2015/05/07 Javascript
关于jquery中动态增加select,事件无效的快速解决方法
2016/08/29 Javascript
微信小程序 本地存储及登录页面处理实例详解
2017/01/11 Javascript
JS 实现随机验证码功能
2017/02/15 Javascript
提高JavaScript执行效率的23个实用技巧
2017/03/01 Javascript
Vue实现动态响应数据变化
2017/04/28 Javascript
详解webpack 配合babel 将es6转成es5 超简单实例
2017/05/02 Javascript
Node.js编写CLI的实例详解
2017/05/17 Javascript
bootstrap 通过加减按钮实现输入框组功能
2017/11/15 Javascript
简单谈谈CommonsChunkPlugin抽取公共模块
2017/12/31 Javascript
详解Vue+ElementUI从零开始搭建自己的网站(一、环境搭建)
2019/04/30 Javascript
layui实现二维码弹窗、并下载到本地的方法
2019/09/25 Javascript
浅析python 内置字符串处理函数的使用方法
2014/06/11 Python
python通过定义一个类实例作为ftp回调方法
2015/05/04 Python
解读Python中degrees()方法的使用
2015/05/18 Python
运行django项目指定IP和端口的方法
2018/05/14 Python
计算机二级python学习教程(2) python语言基本语法元素
2019/05/16 Python
pytorch 模型可视化的例子
2019/08/17 Python
python爬虫 基于requests模块发起ajax的get请求实现解析
2019/08/20 Python
postman传递当前时间戳实例详解
2019/09/14 Python
python 在threading中如何处理主进程和子线程的关系
2020/04/25 Python
pycharm软件实现设置自动保存操作
2020/06/08 Python
JD Sports德国官网:英国领先的运动鞋和运动服饰零售商
2018/02/26 全球购物
应届毕业生自我评价分享
2013/12/15 职场文书
高中生物教学反思
2014/02/05 职场文书
大学秋游活动方案
2014/02/11 职场文书
幼儿园门卫岗位职责范本
2014/07/02 职场文书
培训通知
2015/04/17 职场文书
2015领导干部廉洁自律工作总结
2015/07/23 职场文书
62句有关感恩节文案(推荐收藏)
2019/11/28 职场文书