JS事件派发器EventEmitter

原文地址: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。

 

具体实现

JS事件派发器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]);
         }
     }
 };
JS事件派发器EventEmitter

测试代码:

JS事件派发器EventEmitterJS事件派发器EventEmitter
<!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>
            
JS事件派发器EventEmitter

函数

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

  • on :添加事件监听器
  • off:移除事件监听器
  • emit:派发事件
上一篇:Angular学习(八):Angular组件间的通讯


下一篇:【595】列表、元组的相加操作