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 相关文章推荐
Firefox 无法获取cssRules 的解决办法
Oct 11 Javascript
JS 页面自动加载函数(兼容多浏览器)
May 18 Javascript
js url传值中文乱码之解决之道
Nov 20 Javascript
用js一次改变多个input的readonly属性值的方法
Jun 11 Javascript
jquery拖动层效果插件用法实例分析(附demo源码)
Apr 28 Javascript
基于Jquery插件Uploadify实现实时显示进度条上传图片
Mar 26 Javascript
遍历json 对象的属性并且动态添加属性的实现
Dec 02 Javascript
详解js静态资源文件请求的处理
Aug 01 Javascript
Vue.js 踩坑记之双向绑定
May 03 Javascript
JS同步、异步、延迟加载的方法
May 05 Javascript
jQuery动态操作表单示例【基于table表格】
Dec 06 jQuery
JS实现电商商品展示放大镜特效
Jan 07 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
vBulletin Forum 2.3.xx SQL Injection
2006/10/09 PHP
ThinkPHP整合百度Ueditor图文教程
2014/10/21 PHP
php获取百度收录、百度热词及百度快照的方法
2015/04/02 PHP
PHP中Notice错误常见解决方法
2017/04/28 PHP
prototype 源码中文说明之 prototype.js
2006/09/22 Javascript
Jquery同辈元素选中/未选中效果的实例代码
2013/08/01 Javascript
jquery给图片添加鼠标经过时的边框效果
2013/11/12 Javascript
JS中prototype的用法实例分析
2015/03/19 Javascript
整理Javascript基础入门学习笔记
2015/11/29 Javascript
利用jQuery设计一个简单的web音乐播放器的实例分享
2016/03/08 Javascript
AngularJS基础 ng-submit 指令简单示例
2016/08/03 Javascript
微信小程序(六):列表上拉加载下拉刷新示例
2017/01/13 Javascript
JS身份证信息验证正则表达式
2017/06/12 Javascript
JS实现的简单下拉框联动功能示例
2018/05/11 Javascript
详解webpack引入第三方库的方式以及注意事项
2019/01/15 Javascript
详解Node.js amqplib 连接 Rabbit MQ最佳实践
2019/01/24 Javascript
Nginx设置为Node.js的前端服务器方法总结
2019/03/27 Javascript
vue 微信扫码登录(自定义样式)
2020/01/06 Javascript
k8s node节点重新加入master集群的实现
2021/02/22 Javascript
node.js获取参数的常用方法(总结)
2017/05/29 Python
Pycharm配置远程调试的方法步骤
2018/12/17 Python
Python编程图形库之Pillow使用方法讲解
2018/12/28 Python
python画图把时间作为横坐标的方法
2019/07/07 Python
在tensorflow中实现屏蔽输出的log信息
2020/02/04 Python
基于matplotlib xticks用法详解
2020/04/16 Python
简单了解Python字典copy与赋值的区别
2020/09/16 Python
css3实现信纸/同学录效果的示例代码
2018/12/11 HTML / CSS
vue 中 get / delete 传递数组参数方法
2021/03/23 Vue.js
环境保护与污染治理求职信
2014/07/16 职场文书
2014年办公室工作总结范文
2014/11/12 职场文书
婚礼新人答谢词
2015/01/04 职场文书
教师廉洁自律个人总结
2015/02/10 职场文书
2014年个人年终总结
2015/03/09 职场文书
公司捐书倡议书
2015/04/27 职场文书
go结构体嵌套的切片数组操作
2021/04/28 Golang
Python基础之元类详解
2021/04/29 Python