我有一个页面,其中一些事件监听器附加到输入框和选择框.有没有办法找出哪些事件监听器正在观察特定的DOM节点以及哪些事件?
事件附件使用:
原型的 Event.observe
;
DOM的addEventListener
;
作为元素属性element.onclick
.
Andrew Hedge.. 501
如果您只需要检查页面上发生的情况,可以尝试使用Visual Event书签.
更新:视觉事件2可用;
如果您只需要检查页面上发生的情况,可以尝试使用Visual Event书签.
更新:视觉事件2可用;
这取决于事件的附加方式.为了说明,我们有以下点击处理程序:
var handler = function() { alert('clicked!') };
我们将使用不同的方法将它附加到我们的元素,一些允许检查,一些不允许.
方法A)单个事件处理程序
element.onclick = handler; // inspect alert(element.onclick); // alerts "function() { alert('clicked!') }"
方法B)多个事件处理程序
if(element.addEventListener) { // DOM standard element.addEventListener('click', handler, false) } else if(element.attachEvent) { // IE element.attachEvent('onclick', handler) } // cannot inspect element to find handlers
方法C):jQuery
$(element).click(handler);
1.3.x的
// inspect var clickEvents = $(element).data("events").click; jQuery.each(clickEvents, function(key, value) { alert(value) // alerts "function() { alert('clicked!') }" })
1.4.x(将处理程序存储在对象中)
// inspect var clickEvents = $(element).data("events").click; jQuery.each(clickEvents, function(key, handlerObj) { alert(handlerObj.handler) // alerts "function() { alert('clicked!') }" // also available: handlerObj.type, handlerObj.namespace })
(见jQuery.fn.data
和jQuery.data
)
方法D):原型(凌乱)
$(element).observe('click', handler);
1.5.x的
// inspect Event.observers.each(function(item) { if(item[0] == element) { alert(item[2]) // alerts "function() { alert('clicked!') }" } })
1.6到1.6.0.3,包括在内(这里很难)
// inspect. "_eventId" is for < 1.6.0.3 while // "_prototypeEventID" was introduced in 1.6.0.3 var clickEvents = Event.cache[element._eventId || (element._prototypeEventID || [])[0]].click; clickEvents.each(function(wrapper){ alert(wrapper.handler) // alerts "function() { alert('clicked!') }" })
1.6.1(好一点)
// inspect var clickEvents = element.getStorage().get('prototype_event_registry').get('click'); clickEvents.each(function(wrapper){ alert(wrapper.handler) // alerts "function() { alert('clicked!') }" })
Chrome,Firefox,Vivaldi和Safari getEventListeners(domElement)
在其开发人员工具控制台中提供支持.
对于大多数调试目的,可以使用它.
以下是使用它的非常好的参考:https: //developers.google.com/chrome-developer-tools/docs/commandline-api#geteventlistenersobject
Chrome或Safari浏览器中的WebKit Inspector现在可以执行此操作.当您在"元素"窗格中选择DOM元素时,它将显示DOM元素的事件侦听器.
可以在JavaScript中列出所有事件监听器:这并不难; 你只需要破解prototype
HTML元素的方法(在添加监听器之前).
function reportIn(e){ var a = this.lastListenerInfo[this.lastListenerInfo.length-1]; console.log(a) } HTMLAnchorElement.prototype.realAddEventListener = HTMLAnchorElement.prototype.addEventListener; HTMLAnchorElement.prototype.addEventListener = function(a,b,c){ this.realAddEventListener(a,reportIn,c); this.realAddEventListener(a,b,c); if(!this.lastListenerInfo){ this.lastListenerInfo = new Array()}; this.lastListenerInfo.push({a : a, b : b , c : c}); };
现在每个anchor元素(a
)都有一个lastListenerInfo
包含所有侦听器的属性.它甚至可以用于删除具有匿名功能的侦听器.
在Google Chrome中使用getEventListeners :
getEventListeners(document.getElementByID('btnlogin')); getEventListeners($('#btnlogin'));
(重写这个问题的答案,因为它在这里是相关的.)
调试时,如果你只是想看事件,我建议......
视觉事件
Chrome开发者工具的Elements部分:选择一个元素并在右下方查找"Event Listeners"(类似于Firefox)
如果要在代码中使用事件,并且在1.8版之前使用jQuery ,则可以使用:
$(selector).data("events")
得到事件.从版本1.8开始,使用.data("events")已停止使用(请参阅此错误凭单).您可以使用:
$._data(element, "events")
另一个例子:将特定链接上的所有点击事件写入控制台:
var $myLink = $('a.myClass'); console.log($._data($myLink[0], "events").click);
(有关工作示例,请参见http://jsfiddle.net/HmsQC/)
不幸的是,使用$ ._ data不建议除了调试之外,因为它是一个内部jQuery结构,并且可能在将来的版本中发生变化.不幸的是,我知道没有其他简单的方法可以访问这些事件.
1:Prototype.observe
使用Element.addEventListener(参见源代码)
2:您可以覆盖Element.addEventListener
以记住添加的侦听器(EventListenerList
从DOM3规范提议中删除了方便的属性).在附加任何事件之前运行此代码:
(function() { Element.prototype._addEventListener = Element.prototype.addEventListener; Element.prototype.addEventListener = function(a,b,c) { this._addEventListener(a,b,c); if(!this.eventListenerList) this.eventListenerList = {}; if(!this.eventListenerList[a]) this.eventListenerList[a] = []; this.eventListenerList[a].push(b); }; })();
阅读所有活动:
var clicks = someElement.eventListenerList.click; if(clicks) clicks.forEach(function(f) { alert("I listen to this function: "+f.toString()); });
并且不要忘记覆盖Element.removeEventListener
以从自定义中删除事件Element.eventListenerList
.
3:Element.onclick
酒店需要特别照顾:
if(someElement.onclick) alert("I also listen tho this: "+someElement.onclick.toString());
4:不要忘记Element.onclick
内容属性:这是两个不同的东西:
someElement.onclick = someHandler; // IDL attribute someElement.setAttribute("onclick","otherHandler(event)"); // content attribute
所以你也需要处理它:
var click = someElement.getAttribute("onclick"); if(click) alert("I even listen to this: "+click);
Visual Event bookmarklet(在最流行的答案中提到)只窃取自定义库处理程序缓存:
事实证明,W3C推荐的DOM接口没有提供标准方法来找出哪些事件监听器附加到特定元素.虽然这似乎是一种疏忽,但有人建议将一个名为eventListenerList的属性包含在3级DOM规范中,但遗憾的是在后续草稿中删除了该属性.因此,我们不得不查看各个Javascript库,这些库通常维护附加事件的缓存(以便以后可以删除它们并执行其他有用的抽象).
因此,为了使Visual Event显示事件,它必须能够从Javascript库中解析事件信息.
元素重写可能有问题(即因为有一些DOM特定的功能,如实时集合,无法在JS中编码),但它本身提供了eventListenerList支持,它可以在Chrome,Firefox和Opera中运行(在IE7中不起作用) ).
您可以将本地DOM方法包装为管理事件侦听器,方法是将其置于以下位置:
H/T @ les2
Firefox开发人员工具现在就这样做了.通过单击每个元素显示右侧的"ev"按钮显示事件,包括jQuery和DOM事件.
如果你有Firebug,你可以用来console.dir(object or array)
在任何JavaScript标量,数组或对象的控制台日志中打印一个漂亮的树.
尝试:
console.dir(clickEvents);
要么
console.dir(window);
完全工作的解决方案基于Jan Turon的回答 - 表现得像getEventListeners()
来自控制台:
(有一个重复的小错误.无论如何它都没有破坏.)
(function() { Element.prototype._addEventListener = Element.prototype.addEventListener; Element.prototype.addEventListener = function(a,b,c) { if(c==undefined) c=false; this._addEventListener(a,b,c); if(!this.eventListenerList) this.eventListenerList = {}; if(!this.eventListenerList[a]) this.eventListenerList[a] = []; //this.removeEventListener(a,b,c); // TODO - handle duplicates.. this.eventListenerList[a].push({listener:b,useCapture:c}); }; Element.prototype.getEventListeners = function(a){ if(!this.eventListenerList) this.eventListenerList = {}; if(a==undefined) return this.eventListenerList; return this.eventListenerList[a]; }; Element.prototype.clearEventListeners = function(a){ if(!this.eventListenerList) this.eventListenerList = {}; if(a==undefined){ for(var x in (this.getEventListeners())) this.clearEventListeners(x); return; } var el = this.getEventListeners(a); if(el==undefined) return; for(var i = el.length - 1; i >= 0; --i) { var ev = el[i]; this.removeEventListener(a, ev.listener, ev.useCapture); } }; Element.prototype._removeEventListener = Element.prototype.removeEventListener; Element.prototype.removeEventListener = function(a,b,c) { if(c==undefined) c=false; this._removeEventListener(a,b,c); if(!this.eventListenerList) this.eventListenerList = {}; if(!this.eventListenerList[a]) this.eventListenerList[a] = []; // Find the event in the list for(var i=0;i用法:
someElement.getEventListeners([name])
- 返回事件侦听器列表,如果设置了name,则返回该事件的侦听器数组
someElement.clearEventListeners([name])
- 删除所有事件侦听器,如果设置了name,则仅删除该事件的侦听器
这是一个很好的答案,但我不能让它在`body`和`document`元素上工作.
13> Daniel Sokol..:Opera 12(不是最新的Chrome Webkit引擎)Dragonfly已经有一段时间了,显然在DOM结构中显示.在我看来,它是一个优秀的调试器,是我仍然使用基于Opera 12的版本的唯一原因(没有v13,v14版本和基于v15 Webkit仍然缺乏Dragonfly)