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 相关文章推荐
JavaScript CSS修改学习第五章 给“上传”添加样式
Feb 19 Javascript
js获取下拉列表框中的value和text的值示例代码
Jan 11 Javascript
类似天猫商品详情随浏览器移动的示例代码
Feb 27 Javascript
js对象转json数组的简单实现案例
Feb 28 Javascript
写出高效jquery代码的19条指南
Mar 19 Javascript
wap浏览自动跳转到wap页面的js代码
May 17 Javascript
javascript浏览器窗口之间传递数据的方法
Jan 20 Javascript
Angularjs中的页面访问权限怎么设置
Nov 11 Javascript
jquery实现多次上传同一张图片
Jan 09 Javascript
vue 根据数组中某一项的值进行排序的方法
Aug 30 Javascript
JS返回页面时自动回滚到历史浏览位置
Sep 26 Javascript
在vue中给后台接口传的值为数组的格式代码
Nov 12 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
discuz免激活同步登入代码修改方法(discuz同步登录)
2013/12/24 PHP
php setcookie函数的参数说明及其用法
2014/04/20 PHP
php同时使用session和cookie来保存用户登录信息的实现代码
2016/05/13 PHP
Discuz论坛密码与密保加密规则
2016/12/19 PHP
微信公众平台开发-微信服务器IP接口实例(含源码)
2017/03/05 PHP
PHP用continue跳过本次循环中剩余代码的注意点
2017/06/27 PHP
深入理解PHP+Mysql分布式事务与解决方案
2020/12/03 PHP
js left,right,mid函数
2008/06/10 Javascript
关于二级域名下使用一级域名下的COOKIE的问题
2011/11/07 Javascript
Jquery 数据选择插件Pickerbox使用介绍
2012/08/24 Javascript
Extjs实现进度条的两种便捷方式
2013/09/26 Javascript
浅谈javascript中的instanceof和typeof
2015/02/27 Javascript
Jquery判断radio、selelct、checkbox是否选中及获取选中值方法总结
2015/04/15 Javascript
简单谈谈javascript Date类型
2015/09/06 Javascript
JS实现网页右侧带动画效果的伸缩窗口代码
2015/10/29 Javascript
js正则表达式验证邮件地址
2015/11/12 Javascript
深入理解事件冒泡(Bubble)和事件捕捉(capture)
2016/05/28 Javascript
JavaScript遍历求解数独问题的主要思路小结
2016/06/12 Javascript
jQuery插件echarts实现的去掉X轴、Y轴和网格线效果示例【附demo源码下载】
2017/03/04 Javascript
详解nodejs实现本地上传图片并预览功能(express4.0+)
2017/06/28 NodeJs
Three.js利用dat.GUI如何简化试验流程详解
2017/09/26 Javascript
解决webpack+Vue引入iView找不到字体文件的问题
2018/09/28 Javascript
详解用场景去理解函数柯里化(入门篇)
2019/04/11 Javascript
vue 框架下自定义滚动条(easyscroll)实现方法
2019/08/29 Javascript
解决layer.confirm快速点击会重复触发事件的问题
2019/09/23 Javascript
简单了解Vue + ElementUI后台管理模板
2020/04/07 Javascript
解决Vue 移动端点击出现300毫秒延迟的问题
2020/07/21 Javascript
[58:59]完美世界DOTA2联赛PWL S3 access vs CPG 第一场 12.13
2020/12/16 DOTA
HTML5在IE10、火狐下中文乱码问题的解决方法
2013/11/18 HTML / CSS
html5+css3气泡组件的实现
2014/11/21 HTML / CSS
基于HTML5新特性Mutation Observer实现编辑器的撤销和回退操作
2016/01/11 HTML / CSS
电脑教师的教学自我评价
2013/11/26 职场文书
初中美术教学反思
2014/01/29 职场文书
老公给老婆的检讨书(精华篇)
2014/10/18 职场文书
2016年社区“6.26”禁毒日宣传活动总结
2016/04/05 职场文书
海贼王十大潜力果实,路飞仅排第十,第一可毁世界(震震果实)
2022/03/18 日漫