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提交并解析后台返回的XML的代码
Nov 03 Javascript
JavaScript fontcolor方法入门实例(按照指定的颜色来显示字符串)
Oct 17 Javascript
原生js实现移动端瀑布流式代码示例
Dec 18 Javascript
AngularJS自动表单验证
Feb 01 Javascript
纯js和css完成贪吃蛇小游戏demo
Sep 01 Javascript
ionic 自定义弹框效果
Jun 27 Javascript
React Native 通告消息竖向轮播组件的封装
Aug 25 Javascript
JS遍历DOM文档树的方法实例详解
Apr 03 Javascript
使用Object.defineProperty如何巧妙找到修改某个变量的准确代码位置
Nov 02 Javascript
Angular设置别名alias的方法
Nov 08 Javascript
小程序实现搜索框
Jun 19 Javascript
vue 组件之间事件触发($emit)与event Bus($on)的用法说明
Jul 28 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 daddslashes 使用方法介绍
2012/10/26 PHP
ThinkPHP查询返回简单字段数组的方法
2014/08/25 PHP
php实现的树形结构数据存取类实例
2014/11/29 PHP
php判断对象是派生自哪个类的方法
2015/06/20 PHP
php读取txt文件并将数据插入到数据库
2016/02/23 PHP
Zend Framework教程之Zend_Db_Table表关联实例详解
2016/03/23 PHP
php基于PDO连接MSSQL示例DEMO
2016/07/13 PHP
thinkPHP中配置的读取与C方法详解
2016/12/05 PHP
如何通过View::first使用Laravel Blade的动态模板详解
2017/09/21 PHP
小议Function.apply()之二------利用Apply的参数数组化来提高 JavaScript程序性能
2006/11/30 Javascript
关于全局变量和局部变量的那些事
2013/01/11 Javascript
Jquery 数组操作大全个人总结
2013/11/13 Javascript
JavaScript 作用域链解析
2014/11/13 Javascript
javascript中Date()函数在各浏览器中的显示效果
2015/06/18 Javascript
JS匹配日期和时间的正则表达式示例
2017/05/12 Javascript
Bootstrap Table使用整理(五)之分页组合查询
2017/06/09 Javascript
如何选择适合你的JavaScript框架
2017/11/20 Javascript
Vue中使用Sortable的示例代码
2018/04/07 Javascript
在vue-cli3.0 中使用预处理器 (Sass/Less/Stylus) 配置全局变量操作
2020/08/10 Javascript
python交互式图形编程实例(一)
2017/11/17 Python
Python cookbook(数据结构与算法)筛选及提取序列中元素的方法
2018/03/19 Python
django 控制页面跳转的例子
2019/08/06 Python
使用OpenCV-python3实现滑动条更新图像的Canny边缘检测功能
2019/12/12 Python
网页切图的CSS和布局经验与要点
2015/04/09 HTML / CSS
为你的html5网页添加音效示例
2014/04/03 HTML / CSS
美国南部最大的家族百货公司:Belk
2017/01/30 全球购物
亚马逊印度站:Amazon.in
2017/10/15 全球购物
公司新员工的演讲稿注意事项
2014/01/01 职场文书
物流专业大学的自我评价
2014/01/11 职场文书
《桂花雨》教学反思
2014/04/12 职场文书
员工合理化建议书
2014/05/19 职场文书
小学英语教师先进事迹
2014/05/28 职场文书
三严三实民主生活会发言稿
2014/10/13 职场文书
青年文明号汇报材料
2014/12/23 职场文书
颐和园导游词
2015/01/30 职场文书
解决Mysql多行子查询的使用及空值问题
2022/01/22 MySQL