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 ready(fn)事件使用介绍
Aug 21 Javascript
前台js对象在后台转化java对象的问题探讨
Dec 20 Javascript
javascript 获取元素样式必杀技
May 04 Javascript
删除Javascript Object中间的key
Nov 18 Javascript
JQuery异步获取返回值中文乱码的解决方法
Jan 29 Javascript
深入浅析Bootstrap列表组组件
May 03 Javascript
jQuery+Ajax实现限制查询间隔的方法
Jun 07 Javascript
node.js中实现kindEditor图片上传功能的方法教程
Apr 26 Javascript
node中koa中间件机制详解
Aug 22 Javascript
微信小程序之圆形进度条实现思路
Feb 22 Javascript
JS实现的汉字与Unicode码相互转化功能分析
May 25 Javascript
详解javascript对数组和json数组的操作
Apr 15 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
谷歌音乐搜索栏的提示功能php修正代码
2011/05/09 PHP
比较简单的百度网盘文件直链PHP代码
2013/03/24 PHP
mysql_connect localhost和127.0.0.1的区别(网络层阐述)
2015/03/26 PHP
Yii中的cookie的发送和读取
2016/07/27 PHP
Windows下wamp php单元测试工具PHPUnit安装及生成日志文件配置方法
2018/05/28 PHP
PHP后期静态绑定之self::限制实例分析
2018/12/21 PHP
PHP的mysqli_rollback()函数讲解
2019/01/23 PHP
详解关于php的xdebug配置(编辑器vscode)
2019/01/29 PHP
PHP FileSystem 文件系统常用api整理总结
2019/07/12 PHP
使一个函数作为另外一个函数的参数来运行的javascript代码
2007/08/13 Javascript
html5+javascript制作简易画板附图
2014/04/25 Javascript
IE8中动态创建script标签onload无效的解决方法
2014/12/22 Javascript
jQuery实现ajax调用WCF服务的方法(附带demo下载)
2015/12/04 Javascript
基于javascript编写简单日历
2016/05/02 Javascript
JS使用单链表统计英语单词出现次数
2016/06/16 Javascript
JavaScript探测CSS动画是否已经完成的方法
2016/08/30 Javascript
Bootstrap显示与隐藏简单实现代码
2017/03/06 Javascript
在Node.js中将SVG图像转换为PNG,JPEG,TIFF,WEBP和HEIF格式的方法
2019/08/22 Javascript
layui数据表格跨行自动合并的例子
2019/09/02 Javascript
微信接入之获取用户头像的方法步骤
2019/09/23 Javascript
javascript实现一款好看的秒表计时器
2020/09/05 Javascript
[52:08]DOTA2上海特级锦标赛主赛事日 - 3 败者组第三轮#2Fnatic VS OG第一局
2016/03/05 DOTA
Python实现string字符串连接的方法总结【8种方式】
2018/07/06 Python
django自带的权限管理Permission用法说明
2020/05/13 Python
基于CSS3实现立方体自转效果
2016/03/01 HTML / CSS
html5 datalist 选中option选项后的触发事件
2020/03/05 HTML / CSS
kmart凯马特官网:美国最大的打折零售商和全球最大的批发商之一
2016/11/17 全球购物
Exoticca英国:以最优惠的价格提供豪华异国情调旅行
2018/10/18 全球购物
建筑工程自我鉴定
2013/10/18 职场文书
单位单身证明范本
2014/01/11 职场文书
2014年财务工作总结范文
2014/11/11 职场文书
小学生作文评语集锦
2014/12/25 职场文书
搬迁通知
2015/04/20 职场文书
催款函范文
2015/06/24 职场文书
Golang: 内建容器的用法
2021/05/05 Golang
MySQL安装失败的原因及解决步骤
2022/06/14 MySQL