我正在试图弄清楚如何监听JavaScript对象上的所有事件.
我知道我可以用这样的东西添加个别事件
element.addEventListener("click", myFunction);
element.addEventListener("mouseover", myFunction);
...
Run Code Online (Sandbox Code Playgroud)
我想弄清楚是否有一个全能,我想做这样的事情:
// Begin pseudocode
var myObj = document.getElementById('someID');
myObj.addEventListener(/*catch all*/, myFunction);
function myFunction() {
alert(/*event name*/);
}
// End pseudocode
Run Code Online (Sandbox Code Playgroud)
Rom*_*iev 24
要获取标准元素的事件.
var myObj = document.getElementById('someID');
for(var key in myObj){
if(key.search('on') === 0) {
myObj.addEventListener(key.slice(2), myFunction)
}
}
Run Code Online (Sandbox Code Playgroud)
但正如@jeremywoertink所提到的,任何其他事件也是可能的.
rya*_*uen 17
@ roman-bekkiev答案的更现代的改写:
Object.keys(window).forEach(key => {
if (/^on/.test(key)) {
window.addEventListener(key.slice(2), event => {
console.log(event);
});
}
});
Run Code Online (Sandbox Code Playgroud)
请注意,您可以进一步自定义要捕获的内容,例如:
/^on(key|mouse)/.test(key)
我讨厌这个问题在没有原生或优雅的解决方案的情况下仍然存在。
这允许您CustomEvent为任何EventTarget使用订阅单个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);
Run Code Online (Sandbox Code Playgroud)
当然,更原生或更优雅的方式是使用原生Proxyonapply作为目标的dispatchEvent方法,但对于这篇文章来说,这可能会传达更少的信息。
要点:https : //gist.github.com/cScarlson/875a9fca7ab7084bb608fb66adff0463
显然,这仅在通过EventTargets的dispatchEvent方法驱动事件分派时有效。也就是说,通过鼠标事件(例如)自然触发事件是行不通的。需要有一种方法来包装由自然事件触发器调用的内部方法。
话虽如此,如果您有办法解决这个问题,请在另一个答案中展示您的想法。
据我所知,这是可能的。
\n对于所有本机事件target.onevent,我们可以通过迭代属性并为所有事件安装侦听器来检索支持的事件列表。
for (const key in target) {\n if(/^on/.test(key)) {\n const eventType = key.substr(2);\n target.addEventListener(eventType, listener);\n }\n}\nRun Code Online (Sandbox Code Playgroud)\n 据我所知,发出事件的唯一其他方式是 via EventTarget.dispatchEvent,其中 everyNode和fore everyElement继承。
\n要侦听所有这些手动触发的事件,我们可以dispatchEvent全局代理该方法,并为我们刚刚看到其名称的事件及时安装侦听器 \xe2\x9c\xa8 ^^
const dispatchEvent_original = EventTarget.prototype.dispatchEvent;\nEventTarget.prototype.dispatchEvent = function (event) {\n if (!alreadyListenedEventTypes.has(event.type)) {\n target.addEventListener(event.type, listener, ...otherArguments);\n alreadyListenedEventTypes.add(event.type);\n }\n dispatchEvent_original.apply(this, arguments);\n};\nRun Code Online (Sandbox Code Playgroud)\n 函数片段
\nfunction addEventListenerAll(target, listener, ...otherArguments) {\n\n // install listeners for all natively triggered events\n for (const key in target) {\n if (/^on/.test(key)) {\n const eventType = key.substr(2);\n target.addEventListener(eventType, listener, ...otherArguments);\n }\n }\n\n // dynamically install listeners for all manually triggered events, just-in-time before they\'re dispatched ;D\n const dispatchEvent_original = EventTarget.prototype.dispatchEvent;\n function dispatchEvent(event) {\n target.addEventListener(event.type, listener, ...otherArguments); // multiple identical listeners are automatically discarded\n dispatchEvent_original.apply(this, arguments);\n }\n EventTarget.prototype.dispatchEvent = dispatchEvent;\n if (EventTarget.prototype.dispatchEvent !== dispatchEvent) throw new Error(`Browser is smarter than you think!`);\n\n}\n\n\n// usage example\naddEventListenerAll(window, (evt) => {\n console.log(evt.type);\n});\ndocument.body.click();\ndocument.body.dispatchEvent(new Event(\'omg!\', { bubbles: true }));\n\n\n// usage example with `useCapture`\n// (also receives `bubbles: false` events, but in reverse order)\naddEventListenerAll(\n window,\n (evt) => { console.log(evt.type); },\n true\n);\ndocument.body.dispatchEvent(new Event(\'omfggg!\', { bubbles: false }));\nRun Code Online (Sandbox Code Playgroud)\n