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 相关文章推荐
js获取class的所有元素
Mar 28 Javascript
提高jQuery性能的十个诀窍
Nov 14 Javascript
js实现横向百叶窗效果网页切换动画效果的方法
Mar 02 Javascript
jquery mobile 移动web(5)
Dec 20 Javascript
功能强大的Bootstrap效果展示(二)
Aug 03 Javascript
Bootstrap基本样式学习笔记之图片(6)
Dec 07 Javascript
Vuejs入门教程之Vue生命周期,数据,手动挂载,指令,过滤器
Apr 19 Javascript
Element-ui自定义table表头、修改列标题样式、添加tooltip、:render-header使用
Apr 11 Javascript
JavaScript函数IIFE使用详解
Oct 21 Javascript
javascript跳转与返回和刷新页面的实例代码
Nov 20 Javascript
VueX模块的具体使用(小白教程)
Jun 05 Javascript
vue 组件之间事件触发($emit)与event Bus($on)的用法说明
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
zend Framework中的Layout(模块化得布局)详解
2013/06/28 PHP
php实现parent调用父类的构造方法与被覆写的方法
2015/02/11 PHP
Yii CDBCriteria常用方法实例小结
2017/01/19 PHP
javascript实现的像java、c#之类的sleep暂停的函数代码
2010/03/04 Javascript
基于jquery+thickbox仿校内登录注册框
2010/06/07 Javascript
jQuery实现鼠标移到元素上动态提示消息框效果
2013/10/20 Javascript
jquery上传插件fineuploader上传文件使用方法(jquery图片上传插件)
2013/12/05 Javascript
js创建元素(节点)示例
2014/01/02 Javascript
javascript实现九宫格相加数值相等
2020/05/28 Javascript
Js+Ajax,Get和Post在使用上的区别小结
2016/06/08 Javascript
vue子组件使用自定义事件向父组件传递数据
2017/05/27 Javascript
vue 如何添加全局函数或全局变量以及单页面的title设置总结
2017/06/01 Javascript
一个Js文件函数中调用另一个Js文件函数的方法演示
2017/08/14 Javascript
Vue组件之极简的地址选择器的实现
2018/05/31 Javascript
使用vue-infinite-scroll实现无限滚动效果
2018/06/22 Javascript
JavaScript函数的4种调用方法实例分析
2019/03/05 Javascript
vue组件定义,全局、局部组件,配合模板及动态组件功能示例
2019/03/19 Javascript
vue实现PC端录音功能的实例代码
2019/06/05 Javascript
[04:49]2014DOTA2国际邀请赛 Newbee顺利挺进总决赛 ImbaTV独家专访
2014/07/19 DOTA
python每次处理固定个数的字符的方法总结
2013/01/29 Python
python获取文件后缀名及批量更新目录下文件后缀名的方法
2014/11/11 Python
python  Django中的apps.py的目的是什么
2018/10/15 Python
python实现抽奖小程序
2020/04/15 Python
Python matplotlib生成图片背景透明的示例代码
2019/08/30 Python
Tensorflow不支持AVX2指令集的解决方法
2020/02/03 Python
Python sorted排序方法如何实现
2020/03/31 Python
英国家居用品和家居装饰品购物网站:Cox & Cox
2019/08/25 全球购物
EJB3.1都有哪些改进
2012/11/17 面试题
蔬菜基地的创业计划书
2014/01/06 职场文书
课改先进个人汇报材料
2014/01/26 职场文书
酒店总经理岗位职责范本
2014/08/08 职场文书
师德师风学习材料
2014/12/19 职场文书
公积金具结保证书
2015/05/11 职场文书
《女娲补天》教学反思
2016/02/20 职场文书
goland 设置project gopath的操作
2021/05/06 Golang
分析Java中Map的遍历性能问题
2021/06/26 Java/Android