1

I'm creating a client-side dynamic blog engine. Now I need a event system to handle many actions from DOM elements and the engine. Such as the engine is loading a article,user is switching a theme...

And I don't want to use a library to do this.

So far I've done is using a list to store callbacks for a event.

But I want each callback works with different objects.Like the DOM event.

I may add an id-like property to each object, and store (id,callbacks) in a event.I feel it's not so good.When comes with dynamically generated object,it could be complex to deal with.

How to implement it as simple as DOM event (to use)?

1
  • No. You have to make a start by yourself, do your research, make an attempt and then ask us when you have problems (after searching for an answer first). Or, to improve your (working) code, consider looking at Code Review. But we're not writing it for you. Commented Jun 21, 2014 at 15:02

4 Answers 4

2

Recently, I wanted to add simple event listeners to vanilla JavaScript objects. This is the solution I came up with

(This requires ecmascript >= 5)

function Emitter () {
  var eventTarget = document.createDocumentFragment();

  function delegate (method) {
    this[method] = eventTarget[method].bind(eventTarget);
  }

  Emitter.methods.forEach(delegate, this);
}

Emitter.methods = ["addEventListener", "dispatchEvent", "removeEventListener"];

Now a "class" that uses it

function Example () {
  Emitter.call(this);
}

Let's try it out now!

var e = new Example();

e.addEventListener("something", function(event) {
  alert("something happened! check the console too!");
  console.log(event);
});

e.dispatchEvent(new Event("something"));

Good luck!

Sign up to request clarification or add additional context in comments.

Comments

0

You could implement mediator pattern:

http://addyosmani.com/resources/essentialjsdesignpatterns/book/#mediatorpatternjavascript

In this book is everything you need to know about it.

Comments

0

class SimpleEvent {
  constructor() {
    this.onEvent = {}
    this.handler = function(funct, name) {
      var owner = this
      var name = name
      this.onEvent[name] = funct
      var remove = function() {
        delete this.owner.onEvent[this.name]
        delete this.owner
        delete this.name
        delete this.remove
      }
      if ((((!(remove == undefined && name == undefined)) && (remove == undefined || name == undefined)))) {
        throw new Error("-_-")
      } else {
        return (remove == undefined || name == undefined) ? (undefined) : ({
          remove: remove,
          name: name
        })
      }
    }
  }
  Fire() {
    for (var i in this.onEvent) {
      this.onEvent[i](arguments)
    }
  }
}

Comments

0

ok was recently looking into this settled on this https://github.com/browserify/events#readme just so its consistent in my personal enviroment but I also want to paste in a basic one I found in the slick grid project this is pretty useful for only being 150 lines of code and I think gives a good basic understanding of events

/***
 * An event object for passing data to event handlers and letting them control propagation.
 * <p>This is pretty much identical to how W3C and jQuery implement events.</p>
 * @class EventData
 * @constructor
 */
function EventData() {
  var isPropagationStopped = false;
  var isImmediatePropagationStopped = false;

  /***
   * Stops event from propagating up the DOM tree.
   * @method stopPropagation
   */
  this.stopPropagation = function() {
    isPropagationStopped = true;
  };

  /***
   * Returns whether stopPropagation was called on this event object.
   * @method isPropagationStopped
   * @return {Boolean}
   */
  this.isPropagationStopped = function() {
    return isPropagationStopped;
  };

  /***
   * Prevents the rest of the handlers from being executed.
   * @method stopImmediatePropagation
   */
  this.stopImmediatePropagation = function() {
    isImmediatePropagationStopped = true;
  };

  /***
   * Returns whether stopImmediatePropagation was called on this event object.\
   * @method isImmediatePropagationStopped
   * @return {Boolean}
   */
  this.isImmediatePropagationStopped = function() {
    return isImmediatePropagationStopped;
  };
}

/***
 * A simple publisher-subscriber implementation.
 * @class Event
 * @constructor
 */
function Event() {
  var handlers = [];

  /***
   * Adds an event handler to be called when the event is fired.
   * <p>Event handler will receive two arguments - an <code>EventData</code> and the <code>data</code>
   * object the event was fired with.<p>
   * @method subscribe
   * @param fn {Function} Event handler.
   */
  this.subscribe = function(fn) {
    handlers.push(fn);
  };

  /***
   * Removes an event handler added with <code>subscribe(fn)</code>.
   * @method unsubscribe
   * @param fn {Function} Event handler to be removed.
   */
  this.unsubscribe = function(fn) {
    for (var i = handlers.length - 1; i >= 0; i--) {
      if (handlers[i] === fn) {
        handlers.splice(i, 1);
      }
    }
  };

  /***
   * Fires an event notifying all subscribers.
   * @method notify
   * @param args {Object} Additional data object to be passed to all handlers.
   * @param e {EventData}
   *      Optional.
   *      An <code>EventData</code> object to be passed to all handlers.
   *      For DOM events, an existing W3C/jQuery event object can be passed in.
   * @param scope {Object}
   *      Optional.
   *      The scope ("this") within which the handler will be executed.
   *      If not specified, the scope will be set to the <code>Event</code> instance.
   */
  this.notify = function(args, e, scope) {
    e = e || new EventData();
    scope = scope || this;

    var returnValue;
    for (var i = 0; i < handlers.length && !(e.isPropagationStopped() || e.isImmediatePropagationStopped()); i++) {
      returnValue = handlers[i].call(scope, e, args);
    }

    return returnValue;
  };
}

function EventHandler() {
  var handlers = [];

  this.subscribe = function(event, handler) {
    handlers.push({
      event: event,
      handler: handler
    });
    event.subscribe(handler);

    return this; // allow chaining
  };

  this.unsubscribe = function(event, handler) {
    var i = handlers.length;
    while (i--) {
      if (handlers[i].event === event &&
        handlers[i].handler === handler) {
        handlers.splice(i, 1);
        event.unsubscribe(handler);
        return;
      }
    }

    return this; // allow chaining
  };

  this.unsubscribeAll = function() {
    var i = handlers.length;
    while (i--) {
      handlers[i].event.unsubscribe(handlers[i].handler);
    }
    handlers = [];

    return this; // allow chaining
  };
}

console.log("Start Demo")

car1 = {}
car1.onhonk = new Event();
car1.honk = ()=>{
  console.log('car1 Honked');
  car1.onhonk.notify({noise:'meep meep'}) 
};


car2 = {}
car2.honkListener = (e, args) => {
  console.log("car2 heard: ", args.noise);
}

car1.honk();//not heard yet 

car1.onhonk.subscribe(car2.honkListener);
car1.honk();

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.