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

新手上路,请多包涵

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

myObject.element = document.getElementsByClassName('js-myObject');
myObject.element.addEventListener('click', myObject.click);
myObject.element.addEventListener('mouseover', myObject.mouseover);
//etc..

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

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

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

编辑,我目前的解决方案

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

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

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

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

原文由 Ken Sherman 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 254
2 个回答

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

顺便说一下,您应该使用涉及 myObject.controller 形式的通用事件处理程序的自己的架构,而不是使用涉及 EventListener 接口和它定义的 handleEvent 方法。

原文由 user663031 发布,翻译遵循 CC BY-SA 4.0 许可协议

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

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

 for (const key in target) {
    if(/^on/.test(key)) {
        const eventType = key.substr(2);
        target.addEventListener(eventType, listener);
    }
}

据我所知,事件发出的唯一其他方式是通过 EventTarget.dispatchEvent ,每个 Node 因此每个 Element 继承。

要监听所有这些 手动触发的事件,我们可以在全局代理 dispatchEvent 方法,并为我们刚刚看到其名称的事件及时安装我们的监听器 ✨ ^^

 const dispatchEvent_original = EventTarget.prototype.dispatchEvent;
EventTarget.prototype.dispatchEvent = function (event) {
    if (!alreadyListenedEventTypes.has(event.type)) {
        target.addEventListener(event.type, listener, ...otherArguments);
        alreadyListenedEventTypes.add(event.type);
    }
    dispatchEvent_original.apply(this, arguments);
};

🔥 功能片段 🔥

 function addEventListenerAll(target, listener, ...otherArguments) {

    // install listeners for all natively triggered events
    for (const key in target) {
        if (/^on/.test(key)) {
            const eventType = key.substr(2);
            target.addEventListener(eventType, listener, ...otherArguments);
        }
    }

    // dynamically install listeners for all manually triggered events, just-in-time before they're dispatched ;D
    const dispatchEvent_original = EventTarget.prototype.dispatchEvent;
    function dispatchEvent(event) {
        target.addEventListener(event.type, listener, ...otherArguments);  // multiple identical listeners are automatically discarded
        dispatchEvent_original.apply(this, arguments);
    }
    EventTarget.prototype.dispatchEvent = dispatchEvent;
    if (EventTarget.prototype.dispatchEvent !== dispatchEvent) throw new Error(`Browser is smarter than you think!`);

}

// usage example
function addEventListenerAll(target, listener, ...otherArguments) {

    // install listeners for all natively triggered events
    for (const key in target) {
        if (/^on/.test(key)) {
            const eventType = key.substr(2);
            target.addEventListener(eventType, listener, ...otherArguments);
        }
    }

    // dynamically install listeners for all manually triggered events, just-in-time before they're dispatched ;D
    const dispatchEvent_original = EventTarget.prototype.dispatchEvent;
    function dispatchEvent(event) {
        target.addEventListener(event.type, listener, ...otherArguments);  // multiple identical listeners are automatically discarded
        dispatchEvent_original.apply(this, arguments);
    }
    EventTarget.prototype.dispatchEvent = dispatchEvent;
    if (EventTarget.prototype.dispatchEvent !== dispatchEvent) throw new Error(`Browser is smarter than you think!`);

}

// usage example
addEventListenerAll(window, (evt) => {
    console.log(evt.type);
});
document.body.click();
document.body.dispatchEvent(new Event('omg!', { bubbles: true }));

// usage example with `useCapture`
// (also receives `bubbles: false` events, but in reverse order)
addEventListenerAll(
    window,
    (evt) => { console.log(evt.type); },
    true
);
document.body.dispatchEvent(new Event('omfggg!', { bubbles: false }));

原文由 pitizzzle 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题