如何为javascript中的所有事件添加事件侦听器而不单独列出它们?

Ken*_*man 10 javascript oop model-view-controller

我想使用通配符完成以下代码(我认为不存在?)

myObject.element = document.getElementsByClassName('js-myObject');
myObject.element.addEventListener('click', myObject.click);
myObject.element.addEventListener('mouseover', myObject.mouseover);
//etc..
Run Code Online (Sandbox Code Playgroud)

到目前为止,我有以下内容

myObject.controller = function(e){
   if( (e.type in myObject) && (typeof myObject[e.type] ==='function') ){
      myObject[e.type](e);
   }
};

//but the listeners still have to be assigned as such
myObject.element = document.getElementsByClassName('js-myObject');
myObject.element.addEventListener('click', myObject.controller);
myObject.element.addEventListener('mouseover', myObject.controller);
//etc...


// but I want to do (and it doesn't work)
myObject.element.addEventListener('*', myObject.controller);
Run Code Online (Sandbox Code Playgroud)

除了事件数组和 foreach 语句之外的方法有什么建议吗?

编辑,我目前的解决方案

我已经接受了下面的答案(没有可用的通配符,解析可能有数百个事件是个坏主意)

对于那些寻找类似功能的人,我已经确定了以下方法,至少现在是这样。

for(var prop in myObject){
  if (!myObject.hasOwnProperty(prop){continue;}
  if (typeof myObject[prop] !== 'function'){continue;}
  myObject.element.addEventListener(prop, myObject[prop]);
}
Run Code Online (Sandbox Code Playgroud)

好处是自定义事件的处理程序,我不必返回并为其添加侦听器。缺点是我必须确保在定义每个 myObject.someEvent() 之后调用此函数。我在 myObject.init() 中调用它;这对我来说很好。请注意,此解决方案不符合我以前的规范,因为它使用了 for/each 循环——但它完成了我真正想要完成的工作,非常感谢 @torazaburo 明确定义了我的技术限制和缺乏智慧初步计划。

pit*_*zle 13

addEventListener(\'*\')自己如何实施

\n
\n

对于所有本机事件target.onevent,我们可以通过迭代属性并为所有事件安装侦听器来检索支持的事件列表。

\n
for (const key in target) {\n    if(/^on/.test(key)) {\n        const eventType = key.substr(2);\n        target.addEventListener(eventType, listener);\n    }\n}\n
Run Code Online (Sandbox Code Playgroud)\n
\n

据我所知,发出事件的唯一其他方式是 via EventTarget.dispatchEvent,其中 everyNode和fore everyElement继承。
\n要侦听所有这些手动触发的事件,我们可以dispatchEvent全局代理该方法,并为我们刚刚看到其名称的事件及时安装侦听器 \xe2\x9c\xa8 ^^

\n
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};\n
Run Code Online (Sandbox Code Playgroud)\n
\n

函数片段

\n
function 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\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 }));\n
Run Code Online (Sandbox Code Playgroud)\n


Rev*_*rcs 7

聚会有点晚了,但以下是我添加所有事件侦听器并将它们记录到控制台的方法:

Object.keys(window).forEach(key => {
    if(/./.test(key)){
        window.addEventListener(key.slice(2), event => {
            console.log(key, event)
        })
    }
})
Run Code Online (Sandbox Code Playgroud)


Don*_*dle 5

没有通配符,但是使用 jQuery 您可以拥有 1 个长事件侦听器行,而不是多个。

你如何记录由 jQuery 中的元素触发的所有事件?

像这样:

('body').on("click mousedown mouseup focus blur keydown change dblclick mousemove mouseover mouseout mousewheel keydown keyup keypress textInput touchstart touchmove touchend touchcancel resize scroll zoom select change submit reset",function(e){
     console.log(e);
}); 
Run Code Online (Sandbox Code Playgroud)


小智 5

没有添加*侦听器的功能,我怀疑您是否希望在一个元素上侦听数百个事件。

顺便说一句,myObject.controller您应该使用涉及EventListener接口及其定义的方法的未被充分重视的方法,而不是以 的形式为通用事件处理程序handleEvent自行构建架构。

  • 这在 Chrome 中不起作用。我尝试使用 document.body.addEventListener('*', function(e) { console.log('event', e); });` 它在 Chrome 或 Firefox 中不起作用。真正有效的是个人项目。不起作用的是多个事件。 (2认同)
  • @MrMesees 如果您阅读整个评论,您会注意到上面的代码实际上是 user663031 引用了OP。 (2认同)