原文地址: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. linux网络设置和虚拟机克隆转移之后Error:No suitable device found:no device found for connection 'System eth0'问题解决

    以root用户登录 #vi  /etc/sysconfig/network-scripts/ifcfg-eth0     #编辑配置文件,添加修改以下内容 BOOTPROTO=static   #启用 ...

  2. springmvc 导出excel

    1.pom.xml <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www ...

  3. 大数据和BI商业智能有何区别?有何相关?

    大数据 ≠BI商业智能,大数据也不是传统商业智能的简单升级. 1.大数据和BI两者的区别 BI(BusinessIntelligence)即商业智能,它是企业数据化管理的一整套的方案,用来将企业中现有 ...

  4. Tomcat--安装与部署(一)

    一.Tomcat背景 自从JSP发布之后,推出了各式各样的JSP引擎.Apache Group在完成GNUJSP1.0的开发以后,开始考虑在SUN的JSWDK基础上开发一个可以直接提供Web服务的JS ...

  5. GO的初始简书(二)环境变量设置与说明

    安装GO后你应该做的一些事~ 将自己需要开发的项目加入环境变量中的gopath中 GOPATH其实就一个工作目录   -----正在开发的项目 1首先在本地新建目录 go_work 2 vi ~/.b ...

  6. Java学习笔记——Linux下安装配置MySQL

    山重水复疑无路,柳暗花明又一村 --游山西村 系统:Ubuntu 16.04LTS 1\官网下载mysql-5.7.18-linux-glibc2.5-x86_64.tar.gz2\建立工作组:$su ...

  7. Java泛型的应用——T extends Comparable<? super T>

    在观察Java源码的时候,发现了这么一个写法T extends Comparable<? super T>.不禁纳闷为什么要这么写呢?有什么好处吗,extends和super在这里的作用着 ...

  8. 全局精确流量调度新思路-HttpDNS服务详解

    但凡使用域名来给用户提供服务的互联网企业,都或多或少地无法避免在有中国特色的互联网环境中遭遇到各种域名被缓存.用户跨网访问缓慢等问题.那么对于腾讯这样的域名数量在10万级别的互联网公司来讲,域名解析异 ...

  9. Easy machine learning pipelines with pipelearner: intro and call for contributors

    @drsimonj here to introduce pipelearner – a package I'm developing to make it easy to create machine ...

  10. Weighted Effect Coding: Dummy coding when size matters

    If your regression model contains a categorical predictor variable, you commonly test the significan ...