我想使用通配符完成以下代码(我认为不存在?)
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明确定义技术限制和缺乏智慧初步计划。
答案 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%,但我认为这是您要寻找的。 p>
我们通常在事件中标记的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)
for (const [key, value] of Object.entries(getEventListeners(document))) {
console.log(`${key}`)
}
我会让你对每个人做一些实际的事情,但现在你至少可以看到页面上存在的所有内容,你可以打开 DevTools 并在此页面上尝试它并亲自看看它是否有效。