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

时间:2016-10-10 17:42: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..

到目前为止,我有以下

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明确定义技术限制和缺乏智慧初步计划。

8 个答案:

答案 0 :(得分:3)

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

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

答案 1 :(得分:2)

没有外卡,但是使用jQuery你可以拥有1个长事件监听器行,而不是多个。

How do you log all events fired by an element in 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);
}); 

答案 2 :(得分:2)

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

没有这样的功能,我怀疑你是否想要听一个元素上的数百个事件。

顺便说一句,您应该使用涉及EventListener界面的不充分理解的方法,而不是您自己的{@ 1}}形式的通用事件处理程序。它定义的myObject.controller方法。

答案 3 :(得分:1)

如果这是您要寻找的,我不是100%,但我认为这是您要寻找的。

我们通常在事件中标记的document不包含事件。实际上是祖父母课。

document -> HTMLDocument -> Document (where you could find the onclick* events)

如您所见,我们可以做到这一点。只需在事件开始时修剪 on

Object.keys(document.__proto__.__proto__).reduce((arr, event)=> {
  if(event.startsWith('on')) return [...arr, event.substr(2)];
  return arr;
}, [])

这将返回类似的内容:

["readystatechange", "pointerlockchange", "pointerlockerror", "beforecopy", "beforecut", "beforepaste", "freeze", "resume", "search", "securitypolicyviolation", "visibilitychange", "copy", "cut", "paste", "abort", "blur", "cancel", "canplay", "canplaythrough", "change", "click", "close", "contextmenu", "cuechange", "dblclick", "drag", "dragend", "dragenter", "dragleave", "dragover", "dragstart", "drop", "durationchange", "emptied", "ended", "error", "focus", "formdata", "input", "invalid", "keydown", "keypress", "keyup", "load", "loadeddata", "loadedmetadata", "loadstart", "mousedown", "mouseenter", "mouseleave", "mousemove", "mouseout", "mouseover", "mouseup", "mousewheel", "pause", "play", "playing", "progress", "ratechange", "reset", "resize", "scroll", "seeked", "seeking", "select", "stalled", "submit", "suspend", "timeupdate", "toggle", "volumechange", "waiting", "webkitanimationend", "webkitanimationiteration", "webkitanimationstart", "webkittransitionend", "wheel", "auxclick", "gotpointercapture", "lostpointercapture", "pointerdown", "pointermove", "pointerup", "pointercancel", "pointerover", "pointerout", "pointerenter", "pointerleave", "selectstart", "selectionchange", "animationend", "animationiteration", "animationstart", "transitionend", "fullscreenchange", "fullscreenerror", "webkitfullscreenchange", "webkitfullscreenerror", "pointerrawupdate"]

这只是我很快想到的事情,我相信聪明人会提供更好的答案。您可能还想查看https://developer.mozilla.org/en-US/docs/Web/Events,其中包含您可能需要的内容。

答案 4 :(得分:0)

getElementsByClassName已经返回一个数组,而不是一个元素。就这样做吧。

myObject.element = document.getElementsByClassName('js-myObject');
for(var i=0; i<myObject.element.length; i++){
    myObject.element[i].addEventListener('click', myObject.controller);
    myObject.element[i].addEventListener('mouseover', myObject.controller);
}

编辑...澄清之后..循环和数组仍然有用

var e = ['click', 'hover', 'focus', 'mouseover', 'mouseout'];
myObject.element = document.getElementsByClassName('js-myObject');
for(var i=0; i<myObject.element.length; i++){
    for(var n=0; n<e.length; n++)
        myObject.element[i].addEventListener(e[n], myObject.controller);
}

答案 5 :(得分:0)

类似这样的东西?

        document.addEventListener('click', function (event) {

            if (event.target.closest('.scroll')) {
                // Do something...
            }

            if (event.target.matches('[data-some-attribute]')) {
                // Do something else...
            }

            if (event.target.matches('#my-form')) {
                // Do another t hing...
            }

        }, false)

答案 6 :(得分: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 }));

答案 7 :(得分:0)

查找页面上的所有事件监听器

getEventListeners(document)

Reference

更好地列出它们

for (const [key, value] of Object.entries(getEventListeners(document))) {
      console.log(`${key}`) 
}

我会让你对每个人做一些实际的事情,但现在你至少可以看到页面上存在的所有内容,你可以打开 DevTools 并在此页面上尝试它并亲自看看它是否有效。