Inspect attached event handlers for any DOM element
有没有办法查看 DOM 元素的任何事件附加了哪些函数/代码?使用 Firebug 或任何其他工具。
自 2011 年年中 Chrome 发布以来,Google Chrome 开发者工具中的元素面板就已具备此功能,并且自 2010 年以来 Chrome 开发者频道发布以来。
此外,为所选节点显示的事件侦听器按照它们在捕获和冒泡阶段被触发的顺序。
在 Mac OSX 上点击 command option i 在 Windows 上点击 Ctrl Shift i 在 Chrome
使用传统
使用 DOM 级别 2 事件
作为浏览器扩展的调试工具可以访问这些类型的侦听器,但我不知道实际上有什么。
一些 JS 框架留下了足够多的事件绑定记录来确定他们一直在做什么。 Visual Event 采用这种方法来发现通过一些流行框架注册的侦听器。
Chrome 开发工具最近发布了一些用于监控 JavaScript 事件的新工具。
TL;DR
Listen to events of a certain type using
monitorEvents() .Use
unmonitorEvents() to stop listening.Get listeners of a DOM element using
getEventListeners() .Use the Event Listeners Inspector panel to get information on event listeners.
查找自定义事件
根据我的需要,在 3rd 方代码中发现自定义 JS 事件,以下两个版本的
-
getEventListeners(window) -
getEventListeners(document)
如果您知道事件侦听器附加到您的 DOM 节点,则将传递它而不是
已知事件
如果您知道要监控的事件,例如
您现在应该开始看到控制台中记录的
您可以使用 Allan Jardine 的 Visual Event 来检查页面上几个主要 JavaScript 库中所有当前附加的事件处理程序。它适用于 jQuery、YUI 和其他几个。
Visual Event 是一个 JavaScript 小书签,因此与所有主流浏览器兼容。
您可以通过查看 DOM 来查看直接附加的事件 (element.onclick = handler)。
您可以使用 FireBug 和 FireQuery 在 Firefox 中查看 jQuery 附加的事件。似乎没有任何方法可以使用 FireBug 查看 addEventListener 添加的事件。但是,您可以使用 Chrome 调试器在 Chrome 中查看它们。
您可以扩展您的 javascript 环境来跟踪事件侦听器。用一些代码package(或"重载")本机 addEventListener() 方法,这些代码可以记录从那时起添加的任何事件侦听器。您还必须扩展 HTMLElement.prototype.removeEventListener 以保留准确反映 DOM 中发生的情况的记录。
只是为了说明(未经测试的代码) - 这是一个示例,说明您将如何 \\'wrap\\' addEventListener 在对象本身上记录已注册的事件侦听器:
1 2 3 4 5 6 7 | var nativeMethod = HTMLElement.prototype.addEventListener; HTMLElement.prototype.addEventListener = function (type, listener) { var el = e.currentTarget; if(!(el.eventListeners instanceof Array)) { el.eventListeners = []} el.eventListeners.push({'type':type, 'listener':listener}); nativeMethod.call(el, type, listener); } |
我很好奇@Rolf 的方法是否真的有效。请记住,这是将标准
在测试时我发现,除了一个小故障(他的
,该方法确实有效
-
您始终只在实际元素本身上使用
addEventListener() - 如果您不使用委托事件附件
-
或通过设置
onclick 或oninput 等属性直接分配事件。
我继续研究是否可以使"嗅探"更加通用,并提出了以下修改版本:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 | (nativeMethod=>{ // IIFE-closure to manipulate the standard addEventListener method: HTMLElement.prototype.addEventListener = function (type,fun) { (this.ELL=this.ELL||[]).push([type,fun]); nativeMethod.call(this,type,fun); } })(HTMLElement.prototype.addEventListener); // LIST direct and indirect event attachments for element `el`: function listELfor(el){ const events="click,change,input,keyup,keydown,blur,focus,mouseover,mouseout" .split(",").map(e=>"on"+e); // possible direct event assignments to check up on const evlist = (el.ELL||[]).map(([t,f])=>[t,f.toString()]); events.forEach(e=> el[e] && (evlist[e]=[e.substr(2),el[e].toString()]) ) let p=el.parentNode; if (p.tagName!=="HTML"){ // if available: run function on parent level recursively: evlist[p.tagName+(p.id?'#'+p.id:'')+(p.className?'.'+p.className:'')]=listELfor(el.parentNode); } return evlist; }; // ============ TESTING ========================================== // now, let's do some sample event attachments in different ways: const sp=document.querySelector('h1 span'); // sp = the target SPAN within H1 sp.addEventListener('click',function(e){console.log('first:',e.target)}); sp.addEventListener('click',function(e){console.log('second:',e.target.tagName)}); sp.addEventListener('click',function(e){console.log('third:',e.target.dataset.val)}); // attach an event to the parent node (H1): sp.parentNode.addEventListener('click',function(e){console.log('Click event attached to H1, click-target is',e.target.tagName);}); // and finally, let's also assign an onclick event directly by using the ONCLICK attribute: sp.onclick=e=>console.log('direct onclick on span, text:',e.target.textContent); // Get all event handler functions linked to `sp`? const allHandlers=listELfor(sp); for (id in allHandlers) console.log(id,allHandlers[id]); |
1 2 | h1 span {cursor:pointer} .as-console-wrapper {max-height:85% !important} |
1 2 | Hello, <span data-val="123">THESE WORDS ARE CLICKABLE</span> <p>Some more text here to pad it out. This text should be unresponsive.</p> |
IIFE 结构将
请注意:
Chrome 也会列出这些"额外"的数组属性 - 甚至更多的属性,与父级及其父级的父级事件附件相关,如下所示: