zoukankan      html  css  js  c++  java
  • 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。

    具体实现

    /**
      * 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>
                
    View Code

     

    函数

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

    • on :添加事件监听器
    • off:移除事件监听器
    • emit:派发事件
  • 相关阅读:
    HttpInvoker-----服务端实现
    RMI实现-----客户端的实现
    RMI实现-----服务端的实现
    远程服务(RMI)使用示例
    DispatcherServlet的逻辑处理(下篇)
    DispatcherServlet的逻辑处理(上篇)
    SpringMVC-----DispatcherServlet
    SpringMVC-----ContextLoaderListener
    爬取淘宝笔记本电脑数据(一)
    哔哩哔哩自动播放视频
  • 原文地址:https://www.cnblogs.com/zhtui/p/4625923.html
Copyright © 2011-2022 走看看