JSFiddle - React, Tailwind, and code Playground

by andyw_

HTML

<input type="button" id="trigger" value="trigger" />
<div id="result"></div>

JavaScript

(function( window ) {

  function Observable() {

    this.eventListeners = [];

    /**
     * Get listeners to an event
     * @param evt string [optional] - if set, only gives the
     */
    this.getListeners = function(evt) {
      if (!evt) {
        return eventListeners;
      }

      if ( typeof (evt) == 'string') {
        if (!eventListeners[evt]) {
          return [];
        }
        return evetListeners[evt];
      }

      throw new Exception("Argument given is invalid. Must be a string");
    }
  }

  var self = Observable;
  //reference to Observable type

  /**
   * Add a listener to an Object
   * @param eventName {string} The name of the event to listen to
   * @param fn {function([args])} The function to be invoked when the event is triggered
   */
  Observable.prototype.addListener = function(eventName, fn) {

    if (!(this instanceof self )) {
      throw new Exception("Object is not Observable");
    }

    //if it doesn't exist, bind a new one within a list
    //else, just append it to the current list
    if (!(eventName in this.eventListeners)) {
      this.eventListeners[eventName] = [fn]
    } else {
      this.eventListeners[eventName].push(fn);
    }
  };

  /**
   * Remove a listener from an Object
   * @param eventName {string} the name of the event to be removed from
   * @param fn {function} the listener to be removed
   */
  Observable.prototype.removeListener = function(eventName, fn) {

    if (!(this instanceof self)) {
      throw new Exception("Object is not Observable");
    }

    if (!(eventName in this.eventListeners)) {
      return;
    }

    var fnList = this.eventListeners[eventName];
    var newFnList = [];

    for (var i = 0; i < fnList.length; i++) {
      if (fnList[i] !== fn) {
        newFnList.push(fn);
      }
    }

    //replace listeners
    this.eventListeners[eventName] = newFnList;
  };

  /**
   * Trigger an Event
   * @param eventName {string} the name of the event
   * @param argsEvent...