Listen for all events in JavaScript

I'm trying to figure out how to listen for all events on a JavaScript object.

I know that I can add individual events with something like this

element.addEventListener("click", myFunction);
element.addEventListener("mouseover", myFunction);
...

I'm trying to figure out if there is a catch-all, I'd like to do something like this:

// Begin pseudocode
var myObj = document.getElementById('someID');

myObj.addEventListener(/*catch all*/, myFunction);

function myFunction() {
  alert(/*event name*/);
}
// End pseudocode

Solution 1:

A more modern rewrite of @roman-bekkiev's answer:

Object.keys(window).forEach(key => {
    if (/^on/.test(key)) {
        window.addEventListener(key.slice(2), event => {
            console.log(event);
        });
    }
});

Note that you can further customize what you want to catch, for example:

/^on(key|mouse)/.test(key)

Solution 2:

To pick up standard element's events.

var myObj = document.getElementById('someID');
for(var key in myObj){
    if(key.search('on') === 0) {
       myObj.addEventListener(key.slice(2), myFunction)
    }
}

But as @jeremywoertink mentioned any other events are also possible.

Solution 3:

I hate that this problem persists without a native or elegant solution.

A Better Solution?

This allows you to subscribe to a single CustomEvent for any EventTarget using target.addEventListener('*', ...).

    clear();

    /**
     * @param : source := EventTarget
     *  *   EventTarget.prototype
     *  *   Node (Element, Attr, etc)
     * @usage : [Node].addEventListener('*', ({ detail: e }) => {...}, false);
     */
    function proxyEventTargetSource(source) {
        var emit = source.dispatchEvent;  // obtain reference

        function proxy(event) {
            var { type } = event, any = new CustomEvent('*', { detail: event });  // use original event as detail
            if (!{ '*': true }[ type ]) emit.call(this, any);  // only emit "any" if type is not any.type ('*')
            return emit.call(this, event);
        }

        if ({ 'dispatchEvent': true }[ emit.name ]) source.dispatchEvent = proxy;  // attempt overwrite only if not already set (avoid rewrapping)
        return (source.dispatchEvent === proxy);  // indicate if its set after we try to
    }

    // proxyEventTargetSource(EventTarget.prototype);  // all targets
    proxyEventTargetSource(document);  // single target
    var e = new CustomEvent('any!', { detail: true });
    document.addEventListener('*', (e) => console.log('type: %s, original: %s, e: %O', e.type, e.detail.type, e), false);
    document.dispatchEvent(e);

Granted, a more native or [perhaps] more elegant way would be to use a native Proxy on apply for the target's dispatchEvent method, but that would maybe convey less for the sake of this post.

Gist: https://gist.github.com/cScarlson/875a9fca7ab7084bb608fb66adff0463

Known Issues

Apparently, this only works while driving event-dispatching through EventTargets's dispatchEvent method. That is, naturally triggering events through mouse events (for instance) does not work. There would need to be a way to wrap the internal method being called by natural event-triggers.

That being said, if you have a way around this, please show what you have in another answer.