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:派發事件

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM