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 相关文章推荐
prototype 1.5 &amp; scriptaculous 1.6.1 学习笔记
Sep 07 Javascript
jQuery aminate方法定位到页面具体位置
Dec 26 Javascript
基于jquery和svg实现超炫酷的动画特效
Dec 09 Javascript
JS中创建函数的三种方式及区别
Mar 13 Javascript
Vuejs第十篇之vuejs父子组件通信
Sep 06 Javascript
基于JS设计12306登录页面
Dec 28 Javascript
微信小程序 聊天室简单实现
Apr 19 Javascript
webpack引入eslint配置详解
Jan 22 Javascript
在angularJs中进行数据遍历的2种方法
Oct 08 Javascript
JS栈stack类的实现与使用方法示例
Jan 31 Javascript
javascript 对象 与 prototype 原型用法实例分析
Nov 11 Javascript
keep-alive保持组件状态的方法
Dec 02 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 禁止页面缓存输出
2009/01/07 PHP
解决file_get_contents无法请求https连接的方法
2013/12/17 PHP
php使用cookie保存用户登录的用户名实例
2015/01/26 PHP
基于PHP微信红包的算法探讨
2016/07/21 PHP
swoole和websocket简单聊天室开发
2017/11/18 PHP
ASP中用Join和Array,可以加快字符连接速度的代码
2007/08/22 Javascript
基于JQuery的密码强度验证代码
2010/03/01 Javascript
再说AutoComplete自动补全之实现原理
2011/11/05 Javascript
JS 两日期相减,获得天数的小例子(兼容IE,FF)
2013/07/01 Javascript
javascript显示用户停留时间的简单实例
2013/08/05 Javascript
javascript中简单的进制转换代码实例
2013/10/26 Javascript
jQuery中index()的用法分析
2014/09/05 Javascript
javascript动态设置样式style实例分析
2015/05/13 Javascript
完善的jquery处理机制
2016/02/21 Javascript
JS中使用apply、bind实现为函数或者类传入动态个数的参数
2016/04/26 Javascript
JavaScript实现设计模式中的单例模式的一些技巧总结
2016/05/17 Javascript
详解如何在Vue2中实现组件props双向绑定
2017/03/29 Javascript
Vue2.0生命周期的理解
2018/08/20 Javascript
JavaScript中引用vs复制示例详析
2018/12/06 Javascript
Mpvue中使用Vant Weapp组件库的方法步骤
2019/05/16 Javascript
JavaScript深入V8引擎以及编写优化代码的5个技巧
2019/06/24 Javascript
vue双击事件2.0事件监听(点击-双击-鼠标事件)和事件修饰符操作
2020/07/27 Javascript
JavaScript实现无限轮播效果
2020/11/19 Javascript
[08:17]Ti9 现场cosplay
2019/09/10 DOTA
python django 增删改查操作 数据库Mysql
2017/07/27 Python
谈一谈基于python的面向对象编程基础
2019/05/21 Python
python入门之基础语法学习笔记
2020/02/08 Python
使用JS+CSS3技术:让你的名字动起来
2013/04/27 HTML / CSS
澳大利亚便宜的家庭购物网站:CrazySales
2018/02/06 全球购物
护理学毕业生求职信
2013/11/14 职场文书
银行内勤岗位职责
2014/04/09 职场文书
反邪教教育心得体会
2016/01/15 职场文书
python函数指定默认值的实例讲解
2021/03/29 Python
只用40行Python代码就能写出pdf转word小工具
2021/05/31 Python
Jupyter Notebook 如何修改字体和大小以及更改字体样式
2021/06/03 Python
cypress测试本地web应用
2022/06/01 Javascript