Getting an array of all possible DOM events

I created a multipurpose factory function for the factory event emitter function. With it, I can turn objects into emitters of events. The code for the factory event emitter is below if someone wants to watch or use it.

My question is how can I get a list of events from the DOM. Please note: I am not trying to get a list of related events. I need a list of all possible events. I want to add the pipe method to emitters. This method will take a DOM object and communicate with all possible events, and then when any of these events fires, each of them will trigger an event with the same name in the emitter.

I don’t think there is a way to do this. I'm ready to make a hard-coded array of event names, but if I can get an array for the DOM, it will be much better and will work if the W3C standardizes more types of events.

PS If you work on W3C, it will be such crap that will make everyone hate the DOM. Please stop considering JavaScript as a toy language. It is not a toy language and needs more than your DOM toy.

/** * 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); }); } } } 
+6
source share
3 answers

Here is the 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

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;}) 

PS: the result is an array of event names, such as ["onwebkitpointerlockerror", "onwebkitpointerlockchange", "onwebkitfullscreenerror", "onwebkitfullscreenchange", "onselectionchange", "onselectstart", "onsearch", "onreset", "onpaste", "onbeforepaste", "oncopy"] ... ect.

+5
source

All DOM events start with on . You can skip any instance of Element and list all properties starting with on .

Example. Copy paste the following code into the console (Firefox using Array methods;)):

 [i for(i in document)].filter(function(i){return i.substring(0,2)=='on'&&(document[i]==null||typeof document[i]=='function');}) 

Another way to get events is to look at a specification that shows:

  // event handler IDL attributes [TreatNonCallableAsNull] attribute Function? onabort; [TreatNonCallableAsNull] attribute Function? onblur; [TreatNonCallableAsNull] attribute Function? oncanplay; [TreatNonCallableAsNull] attribute Function? oncanplaythrough; [TreatNonCallableAsNull] attribute Function? onchange; [TreatNonCallableAsNull] attribute Function? onclick; [TreatNonCallableAsNull] attribute Function? oncontextmenu; [TreatNonCallableAsNull] attribute Function? oncuechange; [TreatNonCallableAsNull] attribute Function? ondblclick; [TreatNonCallableAsNull] attribute Function? ondrag; [TreatNonCallableAsNull] attribute Function? ondragend; [TreatNonCallableAsNull] attribute Function? ondragenter; [TreatNonCallableAsNull] attribute Function? ondragleave; [TreatNonCallableAsNull] attribute Function? ondragover; [TreatNonCallableAsNull] attribute Function? ondragstart; [TreatNonCallableAsNull] attribute Function? ondrop; [TreatNonCallableAsNull] attribute Function? ondurationchange; [TreatNonCallableAsNull] attribute Function? onemptied; [TreatNonCallableAsNull] attribute Function? onended; [TreatNonCallableAsNull] attribute Function? onerror; [TreatNonCallableAsNull] attribute Function? onfocus; [TreatNonCallableAsNull] attribute Function? oninput; [TreatNonCallableAsNull] attribute Function? oninvalid; [TreatNonCallableAsNull] attribute Function? onkeydown; [TreatNonCallableAsNull] attribute Function? onkeypress; [TreatNonCallableAsNull] attribute Function? onkeyup; [TreatNonCallableAsNull] attribute Function? onload; [TreatNonCallableAsNull] attribute Function? onloadeddata; [TreatNonCallableAsNull] attribute Function? onloadedmetadata; [TreatNonCallableAsNull] attribute Function? onloadstart; [TreatNonCallableAsNull] attribute Function? onmousedown; [TreatNonCallableAsNull] attribute Function? onmousemove; [TreatNonCallableAsNull] attribute Function? onmouseout; [TreatNonCallableAsNull] attribute Function? onmouseover; [TreatNonCallableAsNull] attribute Function? onmouseup; [TreatNonCallableAsNull] attribute Function? onmousewheel; [TreatNonCallableAsNull] attribute Function? onpause; [TreatNonCallableAsNull] attribute Function? onplay; [TreatNonCallableAsNull] attribute Function? onplaying; [TreatNonCallableAsNull] attribute Function? onprogress; [TreatNonCallableAsNull] attribute Function? onratechange; [TreatNonCallableAsNull] attribute Function? onreset; [TreatNonCallableAsNull] attribute Function? onscroll; [TreatNonCallableAsNull] attribute Function? onseeked; [TreatNonCallableAsNull] attribute Function? onseeking; [TreatNonCallableAsNull] attribute Function? onselect; [TreatNonCallableAsNull] attribute Function? onshow; [TreatNonCallableAsNull] attribute Function? onstalled; [TreatNonCallableAsNull] attribute Function? onsubmit; [TreatNonCallableAsNull] attribute Function? onsuspend; [TreatNonCallableAsNull] attribute Function? ontimeupdate; [TreatNonCallableAsNull] attribute Function? onvolumechange; [TreatNonCallableAsNull] attribute Function? onwaiting; // special event handler IDL attributes that only apply to Document objects [TreatNonCallableAsNull,LenientThis] attribute Function? onreadystatechange; 
+5
source

I read the spec and I confirmed that this is not possible at the moment. Thank you W3C for not providing us with the most basic environmental information!

I managed to get around the problem without sacrificing anything. As I said, the pipe transfers any events from another emitter (for example, the DOM node) to the current emitter. However, I do not need to do anything until someone tries to listen to the event. Internally, what I am doing is communicating with emitters transmitted through channels when people become attached to the current emitter.

I released the library if you are interested in knowing what I did. The code for the pipe is in the pipe() method and on() method.

0
source

Source: https://habr.com/ru/post/908926/


All Articles