Skip to content

Instantly share code, notes, and snippets.

@Jiang-Xuan
Created January 30, 2018 02:46
Show Gist options
  • Save Jiang-Xuan/8372d83cf9dba4c0b5e99cd258cd431c to your computer and use it in GitHub Desktop.
Save Jiang-Xuan/8372d83cf9dba4c0b5e99cd258cd431c to your computer and use it in GitHub Desktop.

Revisions

  1. Jiang-Xuan created this gist Jan 30, 2018.
    60 changes: 60 additions & 0 deletions dom2EventTarget.js
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,60 @@
    /* Simplified implementation of DOM2 EventTarget.
    * http://www.w3.org/TR/DOM-Level-2-Events/events.html#Events-EventTarget
    */

    function EventTarget() {
    this._listeners = {};
    }

    EventTarget.prototype.addEventListener = function(eventType, listener) {
    if (!(eventType in this._listeners)) {
    this._listeners[eventType] = [];
    }
    var arr = this._listeners[eventType];
    // #4
    if (arr.indexOf(listener) === -1) {
    // Make a copy so as not to interfere with a current dispatchEvent.
    arr = arr.concat([listener]);
    }
    this._listeners[eventType] = arr;
    };

    EventTarget.prototype.removeEventListener = function(eventType, listener) {
    var arr = this._listeners[eventType];
    if (!arr) {
    return;
    }
    var idx = arr.indexOf(listener);
    if (idx !== -1) {
    if (arr.length > 1) {
    // Make a copy so as not to interfere with a current dispatchEvent.
    this._listeners[eventType] = arr.slice(0, idx).concat(arr.slice(idx + 1));
    } else {
    delete this._listeners[eventType];
    }
    return;
    }
    };

    EventTarget.prototype.dispatchEvent = function() {
    var event = arguments[0];
    var t = event.type;
    // equivalent of Array.prototype.slice.call(arguments, 0);
    var args = arguments.length === 1 ? [event] : Array.apply(null, arguments);
    // TODO: This doesn't match the real behavior; per spec, onfoo get
    // their place in line from the /first/ time they're set from
    // non-null. Although WebKit bumps it to the end every time it's
    // set.
    if (this['on' + t]) {
    this['on' + t].apply(this, args);
    }
    if (t in this._listeners) {
    // Grab a reference to the listeners list. removeEventListener may alter the list.
    var listeners = this._listeners[t];
    for (var i = 0; i < listeners.length; i++) {
    listeners[i].apply(this, args);
    }
    }
    };

    module.exports = EventTarget;