原文地址:http://zhangyiheng.com/blog/articles/js_event_mitter.html

需求

随着Browser客户端JS越来越复杂,MVC(Client端)设计模式成为一个很好的开发选择, 而MVC开发模式中,最基础的功能就是把Model和View关联起来, 当Model发生变化的时候,View呈现做出相应的调整。

实现此功能最合适的方式莫过于事件Event了, 对于Event大家应该都很熟悉,比如dom中的button,可以通过addEventListener/attachEvent添加click事件处理。

而一般的object对象是没有事件派发功能的,基于此需求,实现了一个EventEmitter。

具体实现

/**
* Created by taozh on 2017/6/22.
* taozh1982@gmail.com
*/
var EventEmitter = function () {
this.__z_e_listeners = {};
};
EventEmitter.prototype.on = function (evt, handler, context) {
var handlers = this.__z_e_listeners[evt];
if (handlers === undefined) {
handlers = [];
this.__z_e_listeners[evt] = handlers;
}
var item = {
handler: handler,
context: context
};
handlers.push(item);
return item;
};
EventEmitter.prototype.off = function (evt, handler, context) {
var handlers = this.__z_e_listeners[evt];
if (handlers !== undefined) {
var size = handlers.length;
for (var i = 0; i < size; i++) {
var item = handlers[i];
if (item.handler === handler && item.context === context) {
handlers.splice(i, 1);
return;
}
}
}
};
EventEmitter.prototype.emit = function (type, event) {
var hanlders = this.__z_e_listeners[type];
if (hanlders !== undefined) {
var size = hanlders.length;
for (var i = 0; i < size; i++) {
var ef = hanlders[i];
var handler = ef.handler;
var context = ef.context;
handler.apply(context, [event]);
}
}
};

测试代码:

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>EventEmitter Test</title>
<script src="./EventEmitter.js"></script>
<script>
var zObj = function () {
this._props = {};
this._emitter = new EventEmitter();
};
zObj.prototype.set = function (key, value) {
var old = this._props[key];
if (old !== value) {
this._props[key] = value;
this.emitChange(key, value, old);
}
};
zObj.prototype.get = function (key) {
return this._props[key];
}; zObj.prototype.onChange = function (handler, context) {
this._emitter.on("change", handler, context);
};
zObj.prototype.offChange = function (handler, context) {
this._emitter.off("change", handler, context);
};
zObj.prototype.emitChange = function (p, nv, ov) {
this._emitter.emit("change", {
source: this,
property: p,
newValue: nv,
oldValue: ov
});
}; var obj = new zObj();
obj.onChange(function (evt) {
console.log(evt)
});
obj.set("id", 1);
obj.set("id", 2);
</script>
</head>
<body>
</body>
</html>

函数

主要有以下三个功能函数:

  • on :添加事件监听器
  • off:移除事件监听器
  • emit:派发事件

JS 事件派发器EventDispatcher的更多相关文章

  1. JS事件派发器EventEmitter

    原文地址:http://zhangyiheng.com/blog/articles/js_event_mitter.html 需求 随着Browser客户端JS越来越复杂,MVC(Client端)设计 ...

  2. 使用lua实现一个简单的事件派发器

    设计一个简单的事件派发器,个人觉得最重要的一点就是如何保证事件派发过程中,添加或删除同类事件,不影响事件迭代顺序和结果,只要解决这一点,其它都好办. 为了使用pairs遍历函数,重写了pairs(lu ...

  3. Unity-自定义事件派发器的两次尝试

    一.前言: 在游戏开发的很多时候,需要引用其他类的方法,但是一旦类多起来了,相互引用会导致引用关系混乱,极其难以阅读. 以前初次做抖音小游戏时,和一位经验老道的cocos程序员合作,看到我写的代码他不 ...

  4. 谷歌浏览器插件-html页面js事件查看器

    谷歌浏览器插件-html页面js事件查看器 1.下载 下载地址:http://files.cnblogs.com/files/graceup/VisualEvent.zip 解压得到文件:Visual ...

  5. 48、[源码]-Spring容器创建-初始化事件派发器、监听器等

    48.[源码]-Spring容器创建-初始化事件派发器.监听器等 8.initApplicationEventMulticaster();初始化事件派发器: 获取BeanFactory 从BeanFa ...

  6. pyglet模块的EventDispatcher(事件派发对象)

    事件派发对象用于处理事件的派发与响应,pyglet的window对象正是继承了它才具有处理事件的能力. 步骤: 1.注册事件类型: EventDispatcher.register_event_typ ...

  7. cocos2d JS 自定义事件分发器(接收与传递数据) eventManager

    简而言之,它不是由系统自动触发,而是人为的干涉 较多情况用于传递数据 var _listener1 = cc.EventListener.create({ event: cc.EventListene ...

  8. 项目记录22-- tolua基于lua框架事件派发

     每天晚上抽点时间写一点点就一点点,曾经不写博客可是如今.不为别的仅仅是为了告诉别人我还存在.         这几天在地铁上发现好多人都还在玩消除游戏,今天起码看到5个人,可是玩的版本号都不一样.看 ...

  9. js事件绑定及深入

    学习要点: 1.传统事件绑定的问题2.W3C事件处理函数3.IE事件处理函数4.事件对象的其他补充 事件绑定分为两种:一种是传统事件绑定(内联模型,脚本模型),一种是现代事件绑定(DOM2级模型).现 ...

随机推荐

  1. selenium IDE的3种下载安装方式

    第一种方式: 打开firefox浏览器-----点击右上角-----附加组件----插件----搜索框输入“selenium”-----搜索的结果中下拉到页面尾部,点击“查看全部的37项结果”---进 ...

  2. 一个大数据平台省了20个IT人力——敦奴数据平台建设案例分享

    认识敦奴 敦奴集团创立于1987年,主营服装.酒店.地产,总部位于中国皮都-海宁.浙江敦奴联合实业股份有限公司(以下简称"敦奴")是一家集开发.设计.生产.销售于一体的大型专业服装 ...

  3. Java 通过先序后序序列生成二叉树

    题目 二叉树的前序以及后续序列,以空格间隔每个元素,重构二叉树,最后输出二叉树的三种遍历方式的序列以验证. 输入: 1 2 3 4 5 6 7 8 9 10 3 2 5 4 1 7 8 6 10 9 ...

  4. JEESZ-kafka消息服务平台实现

    JEESZ的消息服务平台已经抛弃了之前的ActiveMQ,改用高吞吐量比较大的Kafka分布式消息中间件方案:JEESZ-kafka消息平台使用spring+kafka的集成方案,详情如下:1. 使用 ...

  5. 自定义ScriptableObject属性显示

    自定义ScriptableObject属性显示的三种方式 1. 继承Editor,重写OnInspectorGUI方法 Editor官方文档 需求 将TestClass中intData属性和strin ...

  6. c# 对加密的MP4文件进行解密

    using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; usin ...

  7. bash下. : () {} [] [[]] (())的解释 (非原创,侵删)

    Copy from http://blog.chinaunix.net/uid-20380484-id-1692999.html bash下有很多像{}.[]等一些符号命令,下面是我对一些常用的符号命 ...

  8. 2016 UESTC Training for Dynamic Programming

    强行做做试试看吧. http://acm.hust.edu.cn/vjudge/contest/124721#overview 密码:mytrain C - 柱爷与咸鱼神功 一个简单01背包. #in ...

  9. xml 和html 语言区别

    都是标记语言(ML),一个是超文本标记语言,一个是扩展标记语言. 不同之处: 1可扩展性:HTML不具备扩展性,而XML是原标记语言,可以用于定义新的标记语言. 2侧重点: HTML侧重于如何表现信息 ...

  10. 开涛spring3(7.4) - 对JDBC的支持 之 7.4 Spring提供的其它帮助

    7.4  Spring提供的其它帮助 7.4.1  SimpleJdbc方式 Spring JDBC抽象框架提供SimpleJdbcInsert和SimpleJdbcCall类,这两个类通过利用JDB ...