Listen for all events in JavaScript

后端 未结 6 1578
天涯浪人
天涯浪人 2020-11-28 13:35

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

eleme         


        
6条回答
  •  栀梦
    栀梦 (楼主)
    2020-11-28 13:58

    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.

提交回复
热议问题