Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Getting an array of all DOM events possible

I've created a multi purpose factory event emitter factory function. With it I can turn objects into event emitters. The code for the event emitter factory is below if anyone would like to have a look or use it.

My question is how can I get a list of events from the DOM. Please note I'm not trying to get a list of bound events. I want a list of all events possible. I want to add a "pipe" method to emitters. This method would take a DOM object and bind to all possible events, then when any of those events fire each would trigger an event of the same name in the emitter.

I don't imagine there is a way to do this. I'm prepared to make a hard coded array of event names, but if I can get the array for the DOM instead that would be much better and would still work if the W3C standardizes more event types.

P.S. If you work for the W3C this is the kind of crap that makes everyone hate the DOM. Please stop treating JavaScript like a toy language. It is not a toy language and needs more than your toy DOM.

/**
 * Creates a event emitter
 */
function EventEmitter() {
    var api, callbacks;

    //vars
    api = {
        "on": on,
        "trigger": trigger
    };
    callbacks = {};

    //return the api
    return api;

    /**
     * Binds functions to events
     * @param event
     * @param callback
     */
    function on(event, callback) {
        var api;

        if(typeof event !== 'string') { throw new Error('Cannot bind to event emitter. The passed event is not a string.'); }
        if(typeof callback !== 'function') { throw new Error('Cannot bind to event emitter. The passed callback is not a function.'); }

        //return the api
        api = {
            "clear": clear
        };

        //create the event namespace if it doesn't exist
        if(!callbacks[event]) { callbacks[event] = []; }

        //save the callback
        callbacks[event].push(callback);

        //return the api
        return api;

        function clear() {
            var i;
            if(callbacks[event]) {
                i = callbacks[event].indexOf(callback);
                callbacks[event].splice(i, 1);

                if(callbacks[event].length < 1) {
                    delete callbacks[event];
                }

                return true;
            }
            return false;
        }
    }

    /**
     * Triggers a given event and optionally passes its handlers all additional parameters
     * @param event
     */
    function trigger(event    ) {
        var args;

        if(typeof event !== 'string' && !Array.isArray(event)) { throw new Error('Cannot bind to event emitter. The passed event is not a string or an array.'); }

        //get the arguments
        args = Array.prototype.slice.apply(arguments).splice(1);

        //handle event arrays
        if(Array.isArray(event)) {

            //for each event in the event array self invoke passing the arguments array
            event.forEach(function(event) {

                //add the event name to the begining of the arguments array
                args.unshift(event);

                //trigger the event
                trigger.apply(this, args);

                //shift off the event name
                args.shift();

            });

            return;
        }

        //if the event has callbacks then execute them
        if(callbacks[event]) {

            //fire the callbacks
            callbacks[event].forEach(function(callback) { callback.apply(this, args); });
        }
    }
}
like image 977
Robert Hurst Avatar asked Feb 20 '12 21:02

Robert Hurst


People also ask

What is the sequence of DOM event life cycle?

The event journey starts at the Document, moves down to the HTML element, moves to the Body element, and finally gets to the Button element. The event then bubbles back up to Document, moving again through the Body element and HTML element on its way up.

How to use mouse click event in JavaScript?

Use addEventListener() method to register a mouse event handler. The event. button indicates which mouse button was pressed to trigger the mouse event. The modifier keys: alt, shift, ctrl, and meta (Mac) can be obtained via properties of the event object passed to the mouse event handler.


1 Answers

Here is a version that works in Chrome, Safari and FF.

Object.getOwnPropertyNames(document).concat(Object.getOwnPropertyNames(Object.getPrototypeOf(Object.getPrototypeOf(document)))).filter(function(i){return !i.indexOf('on')&&(document[i]==null||typeof document[i]=='function');})

UPD 1:

And here is the version that works in IE9+, Chrome, Safari and FF.

Object.getOwnPropertyNames(document).concat(Object.getOwnPropertyNames(Object.getPrototypeOf(Object.getPrototypeOf(document)))).concat(Object.getOwnPropertyNames(Object.getPrototypeOf(window))).filter(function(i){return !i.indexOf('on')&&(document[i]==null||typeof document[i]=='function');}).filter(function(elem, pos, self){return self.indexOf(elem) == pos;})

UPD 2:

And here's a version using newer JavaScript features (the [...new Set(...)] is to filter out duplicates, replacing the filter approach).

[...new Set([
 ...Object.getOwnPropertyNames(document),
 ...Object.getOwnPropertyNames(Object.getPrototypeOf(Object.getPrototypeOf(document))),
 ...Object.getOwnPropertyNames(Object.getPrototypeOf(window)),
].filter(k => k.startsWith("on") && (document[k] == null || typeof document[k] == "function")))];

PS: the result is an array of events name like ["onwebkitpointerlockerror", "onwebkitpointerlockchange", "onwebkitfullscreenerror", "onwebkitfullscreenchange", "onselectionchange", "onselectstart", "onsearch", "onreset", "onpaste", "onbeforepaste", "oncopy"] ... ect.

like image 175
obenjiro Avatar answered Sep 22 '22 15:09

obenjiro