我创建了一个多用途工厂事件发射器工厂功能。有了它,我可以将对象转换为事件发射器。如果有人想要查看或使用它,事件发射器工厂的代码如下。
我的问题是如何从DOM中获取事件列表。 请注意我不是要获取绑定事件列表。我想要一个可能的所有事件的列表。我想向发射器添加“管道”方法。此方法将获取DOM对象并绑定到所有可能的事件,然后当任何这些事件触发时,将触发发射器中具有相同名称的事件。
我认为没有办法做到这一点。我准备制作一个硬编码的事件名称数组,但是如果我可以获得更好的DOM数组,那么如果W3C标准化了更多的事件类型,它仍然可以工作。
P.S。如果你为W3C工作,这就是让每个人都讨厌DOM的垃圾。请停止像玩具语言一样对待JavaScript。它不是玩具语言,需要的不仅仅是玩具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); });
}
}
}
答案 0 :(得分:6)
以下版本适用于Chrome,Safari和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 强> :
这是适用于IE9 +,Chrome,Safari和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:结果是一系列事件名称,如["onwebkitpointerlockerror", "onwebkitpointerlockchange", "onwebkitfullscreenerror", "onwebkitfullscreenchange", "onselectionchange", "onselectstart", "onsearch", "onreset", "onpaste", "onbeforepaste", "oncopy"]
...等。
答案 1 :(得分:5)
所有DOM事件均以on
开头。您可以遍历任何Element
实例,并列出以on
开头的所有属性。
实施例。在控制台中复制粘贴以下代码(Firefox,使用Array comprehensions;)):
[i for(i in document)].filter(function(i){return i.substring(0,2)=='on'&&(document[i]==null||typeof document[i]=='function');})
获取事件的另一种方法是查看the specification,其中显示:
// 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;
答案 2 :(得分:0)
我已经阅读了规范,并且我已经确认目前无法进行此操作。感谢W3C没有为我们提供最基本的环境!
我设法绕过这个问题而不牺牲任何东西。正如我之前所说,管道将来自另一个发射器(例如DOM节点)的任何事件传输到当前发射器。但是,在有人试图听一个事件之前,我不需要做任何事情。在内部我所做的是绑定到管道发射器,因为人们绑定到当前发射器。
如果你好奇我能做什么,我released the library。管道代码采用pipe()
方法和on()
方法。
答案 3 :(得分:0)
在过去的一个世纪,当我为IE进行构建相当于在全世界87%到92%的范围内构建建筑时,这就是我用来获得动态eventList
的方式。这是一个像::: eventList = []; for( var x in this )if( x.match(/\bon/) )eventList.push(x);
这样的单行代码,我刚刚在赢7的最新Opera,IE11,相当老的Chrome和大约2年的Firefox上进行了测试...和该死的(!)-就像是一种魅力。
var eventList = [];
for( var x in this )if( /\bon/.test(x) )eventList.push(x),
console.info( x );
console.info( eventList.length );
答案 4 :(得分:0)
您可能没有一个详尽的清单,因为我们可以触发任何名称的综合事件。
例如:
// Since we can even make it bubble
// overriding dispatchEvent wouldn't do either.
// Here we listen on document
document.addEventListener("foo", evt => console.log("foo fired"));
const event = new Event("foo", { bubbles: true });
// And we fire on <body>
document.body.dispatchEvent( event );
几乎没有所有“内置”事件的列表。这些事件中有许多没有在任何地方公开的.onevent
IDL属性,例如Document或Window的DOMContentLoaded
,也没有输入元素compositionXXX
或隐藏在各种规范中的许多其他元素。
// won't fire
window.onDOMContentLoaded = evt => console.log('caught through onDOMContentLoaded');
// will fire
window.addEventListener('DOMContentLoaded', evt => console.log('caught through addEventListener'));
即使捕获所有这些onevent
的IDL属性,也需要遍历所有Constructor的原型,因为window
仅暴露了其中的一些。
console.log("onaddtrack available in window?", "onaddtrack" in window);
console.log("onaddtrack available in MediaStream's proto?", "onaddtrack" in MediaStream.prototype);
虽然我们可以在线找到quite big lists个此类事件,但由于规格不断变化,并且浏览器不支持规格中的所有内容,或者相反,它们不支持规格中未包含的功能,列表将全部捕获。
(例如,最后一点,dragexit event当前仅在Firefox支持的情况下才从规范中删除。)