JavaScript中自定义事件用法分析


Posted in Javascript onDecember 23, 2014

本文实例讲述了JavaScript中自定义事件用法。分享给大家供大家参考。具体分析如下:

在web前端开发中,很多人可能不会用到js的自定义事件,但如果是做一个相对来说比较大的项目,尤其是多人协同开发的时候,自定义事件就显得很重要了。那么,什么是js中的自定义事件呢?我们先来看一个例子:
前端开发员A封装了一个函数:

function move(){

    alert(a);  //以此来代表N行代码

}

过段时间,前端开发员B要在A的基础上丰富这个函数,于是,他会这样写:
function move(){

    alert(a);  //以此来代表N行代码

    alert(b);  //以此来代表N行代码

}

是不是发现了问题,B要注意和A的变量、函数等等的命名和冲突问题,又过段时间,前端开发员C也要丰富这个函数,于是:
function move(){

    alert(a);  //以此来代表N行代码

    alert(b);  //以此来代表N行代码

    alert(c);  //以此来代表N行代码

}

这时候会很令人抓狂了,C写起代码来我敢肯定不会很轻松。解决这个问题的方法就是通过自定义事件,我们知道一个元素身上可以添加相同的事件而不会各自影响,如:
window.addEventListener('click',function(){

    alert(1);

} ,false);

window.addEventListener('click',function(){

    alert(2);

} ,false);

点击页面的时候,1和2都会弹出,那么我们就可以用这种方法来定义我们的函数:
window.addEventListener('move',function(){

    alert(3);

} ,false);

window.addEventListener('move',function(){

    alert(4);

} ,false);

这样,我们执行move();的时候就会弹出3和4,这里的move就是自定义事件,它其实就是一个函数

下面看看如何给事件处理程序传递参数:

//将有参数的函数封装为无参数的函数 

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程序设计有所帮助。

Javascript 相关文章推荐
jquery实现居中弹出层代码
Aug 25 Javascript
在jQuery1.5中使用deferred对象 着放大镜看Promise
Mar 12 Javascript
jQuery Tab插件 用于在Tab中显示iframe,附源码和详细说明
Jun 27 Javascript
解析offsetHeight,clientHeight,scrollHeight之间的区别
Nov 20 Javascript
jQuery用FormData实现文件上传的方法
Nov 21 Javascript
Angular4学习笔记之根模块与Ng模块
Sep 09 Javascript
从源码看angular/material2 中 dialog模块的实现方法
Oct 18 Javascript
解读ES6中class关键字
Nov 20 Javascript
JS实现选项卡效果的代码实例
May 20 Javascript
Promise扫盲贴
Jun 24 Javascript
vue中根据时间戳判断对应的时间(今天 昨天 前天)
Dec 20 Javascript
JS实现audio音频剪裁剪切复制播放与上传(步骤详解)
Jul 28 Javascript
jQuery中even选择器的定义和用法
Dec 23 #Javascript
javascript实现依次输入input自动定焦
Dec 23 #Javascript
使用原生JS实现弹出层特效
Dec 22 #Javascript
jQuery基础知识小结
Dec 22 #Javascript
jQuery异步获取json数据方法汇总
Dec 22 #Javascript
jQuery的观察者模式详解
Dec 22 #Javascript
使用jQuery和Bootstrap实现多层、自适应模态窗口
Dec 22 #Javascript
You might like
风味层面去分析咖啡油脂
2021/03/03 咖啡文化
PHP基础教程(php入门基础教程)一些code代码
2013/01/06 PHP
ThinkPHP之用户注册登录留言完整实例
2014/07/22 PHP
Zend Framework教程之MVC框架的Controller用法分析
2016/03/07 PHP
PHP中的print_r 与 var_dump 输出数组
2016/06/13 PHP
php中二分法查找算法实例分析
2016/09/22 PHP
Linux平台php命令行程序处理管道数据的方法
2016/11/10 PHP
浅谈PHP的exec()函数无返回值排查方法(必看)
2017/03/31 PHP
js树形控件脚本代码
2008/07/24 Javascript
js中的string.format函数代码
2020/08/11 Javascript
javascript函数中参数传递问题示例探讨
2014/07/31 Javascript
jquery获取当前日期的方法
2015/01/14 Javascript
《JavaScript高级编程》学习笔记之object和array引用类型
2015/11/01 Javascript
浅谈js函数中的实例对象、类对象、局部变量(局部函数)
2016/11/20 Javascript
js select下拉联动 更具级联性!
2020/04/17 Javascript
Angular 4.x 路由快速入门学习
2017/05/03 Javascript
jQuery实现节点的追加、替换、删除、复制功能示例
2017/07/11 jQuery
vue文件运行的方法教学
2019/02/12 Javascript
Element Cascader 级联选择器的使用示例
2020/07/27 Javascript
Python对象体系深入分析
2014/10/28 Python
Python之Web框架Django项目搭建全过程
2017/05/02 Python
django实现前后台交互实例
2017/08/07 Python
对Xpath 获取子标签下所有文本的方法详解
2019/01/02 Python
pip install python 快速安装模块的教程图解
2019/10/08 Python
英国家庭珠宝商:T. H. Baker
2018/02/08 全球购物
党建工作先进材料
2014/05/02 职场文书
孝敬父母的活动方案
2014/08/31 职场文书
2014政府领导班子对照检查材料思想汇报(3篇)
2014/09/26 职场文书
教师个人自我剖析材料
2014/09/29 职场文书
社区敬老月活动总结
2015/05/07 职场文书
给老师的保证书怎么写
2015/05/09 职场文书
Go缓冲channel和非缓冲channel的区别说明
2021/04/25 Golang
用Python创建简易网站图文教程
2021/06/11 Python
HTML5 新增内容和 API详解
2021/11/17 HTML / CSS
Mybatis-Plus 使用 @TableField 自动填充日期
2022/04/26 Java/Android
python双向链表实例详解
2022/05/25 Python