How to find event listeners on a DOM node when debugging or from the JavaScript code?
我有一个页面,其中一些事件监听器连接到输入框和选择框。有没有一种方法可以查明哪些事件监听器正在观察特定的DOM节点以及哪些事件?
事件附加使用:
如果你只需要检查页面上发生了什么,你可以试试可视事件书签。
更新:可视事件2可用;
这取决于事件的附加方式。对于示例,假设我们有以下单击处理程序:
1 | var handler = function() { alert('clicked!') }; |
我们将使用不同的方法将它附加到元素上,有些方法允许检查,有些方法不允许检查。
方法a)单个事件处理程序
1 2 3 | element.onclick = handler; // inspect alert(element.onclick); // alerts"function() { alert('clicked!') }" |
方法b)多个事件处理程序
1 2 3 4 5 6 | 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
1 | $(element).click(handler); |
1.3、X
1
2
3
4
5// inspect
var clickEvents = $(element).data("events").click;
jQuery.each(clickEvents, function(key, value) {
alert(value) // alerts"function() { alert('clicked!') }"
})1.4.x(将处理程序存储在对象内)
1
2
3
4
5
6// 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
})
(见
方法D):原型(杂乱)
1 | $(element).observe('click', handler); |
1.5、X
1
2
3
4
5
6// inspect
Event.observers.each(function(item) {
if(item[0] == element) {
alert(item[2]) // alerts"function() { alert('clicked!') }"
}
})1.6至1.6.0.3,包括在内(这里非常困难)
1
2
3
4
5
6// 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(稍好一点)
1
2
3
4
5// 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在其开发工具控制台中支持
对于大多数调试目的,可以使用这个。
以下是使用它的很好参考:https://developers.google.com/chrome developer tools/docs/commandline api getEventListenersObject
Chrome浏览器或Safari浏览器中的WebKit浏览器现在可以执行此操作。当您在元素窗格中选择某个DOM元素时,它将显示该元素的事件侦听器。
可以用javascript列出所有事件监听器:这并不难;您只需黑客处理
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | 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}); }; |
现在,每个锚元素(
在Google Chrome中使用GetEventListeners:
1 2 | getEventListeners(document.getElementByID('btnlogin')); getEventListeners($('#btnlogin')); |
(重写此问题的答案,因为它与此处相关。)
调试时,如果您只想查看事件,我建议您…
如果要在代码中使用事件,并且在1.8版之前使用jquery,则可以使用:
1 | $(selector).data("events") |
以获取活动。从1.8版开始,不再使用.data("events")(请参阅此错误通知单)。你可以使用:
1 | $._data(element,"events") |
另一个示例:在控制台的某个链接上写入所有单击事件:
1 2 | var $myLink = $('a.myClass'); console.log($._data($myLink[0],"events").click); |
(有关工作示例,请参阅http://jsfiddle.net/hmsqc/)
不幸的是,除了调试之外,不建议使用$.u数据,因为它是一个内部jquery结构,在将来的版本中可能会发生更改。不幸的是,我知道没有其他简单的方法来访问这些事件。
1:使用element.addeventlistener
2:你可以重写
1 2 3 4 5 6 7 8 9 | (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); }; })(); |
所有的事件::阅读
1 2 3 4 | var clicks = someElement.eventListenerList.click; if(clicks) clicks.forEach(function(f) { alert("I listen to this function:"+f.toString()); }); |
不要忘了与消除对重写
3:特殊保健需要在
1 2 | if(someElement.onclick) alert("I also listen tho this:"+someElement.onclick.toString()); |
4:不要忘了
1 2 | someElement.onclick = someHandler; // IDL attribute someElement.setAttribute("onclick","otherHandler(event)"); // content attribute |
所以你需要把它,太。
1 2 | var click = someElement.getAttribute("onclick"); if(click) alert("I even listen to this:"+click); |
视觉事件的书签(中提到的最流行的答案只有在自定义处理程序:steals库缓存
It turns out that there is no standard method provided by the W3C
recommended DOM interface to find out what event listeners are
attached to a particular element. While this may appear to be an
oversight, there was a proposal to include a property called
eventListenerList to the level 3 DOM specification, but was
unfortunately been removed in later drafts. As such we are forced to
looked at the individual Javascript libraries, which typically
maintain a cache of attached events (so they can later be removed and
perform other useful abstractions).As such, in order for Visual Event to show events, it must be able to
parse the event information out of a Javascript library.
overriding元(即可能是可疑的,因为有一些具体特点收藏类礼品可以是不带电的,但它在JS编码),使它的工作的支持和eventlistenerlist natively在Firefox和Opera浏览器(IE7中的工作,是不是)。
你可以管理本地的礼品包装方法通过把这一事件侦听器在顶部你的
1 2 3 4 5 6 7 8 9 10 11 12 13 | (function(w){ var originalAdd = w.addEventListener; w.addEventListener = function(){ // add your own stuff here to debug return originalAdd.apply(this, arguments); }; var originalRemove = w.removeEventListener; w.removeEventListener = function(){ // add your own stuff here to debug return originalRemove.apply(this, arguments); }; })(window); |
H / T"les2
火狐开发工具现在不在这。事件是由clicking所示的"EV"按钮右上显示的每个元素,包括jQuery的DOM和事件。
如果有firebug,可以使用
尝试:
1 | console.dir(clickEvents); |
或
1 | console.dir(window); |
基于解决方案的全工作的简-样的答案表现得很
有一个小bug(与duplicates。它不是破多反正)。
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 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 | (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<this.eventListenerList[a].length;i++){ if(this.eventListenerList[a][i].listener==b, this.eventListenerList[a][i].useCapture==c){ // Hmm.. this.eventListenerList[a].splice(i, 1); break; } } if(this.eventListenerList[a].length==0) delete this.eventListenerList[a]; }; })(); |
用法:
Opera 12(不是最新的基于Chrome Webkit引擎的)Dragonfly已经有一段时间了,并且明显显示在DOM结构中。在我看来,它是一个优秀的调试器,也是我仍然使用基于Opera 12的版本的唯一原因(没有V13、V14版本,而基于V15的Webkit仍然缺少Dragonfly)
原型1.7.1方式
1 2 3 4 5 6 7 8 9 10 | function get_element_registry(element) { var cache = Event.cache; if(element === window) return 0; if(typeof element._prototypeUID === 'undefined') { element._prototypeUID = Element.Storage.UID++; } var uid = element._prototypeUID; if(!cache[uid]) cache[uid] = {element: element}; return cache[uid]; } |
有漂亮的jQuery事件存在的扩展:
(题目源码)
我想是在2.1和jQuery的,与"
我意识到,只有美元。_日期()函数的作品在我的案例:
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 | $(document).ready(function(){ var node = $('body'); // Bind 3 events to body click node.click(function(e) { alert('hello'); }) .click(function(e) { alert('bye'); }) .click(fun_1); // Inspect the events of body var events = $._data(node[0],"events").click; var ev1 = events[0].handler // -> function(e) { alert('hello') var ev2 = events[1].handler // -> function(e) { alert('bye') var ev3 = events[2].handler // -> function fun_1() $('body') .append('<p> Event1 = ' + eval(ev1).toString() + ' </p>') .append('<p> Event2 = ' + eval(ev2).toString() + ' </p>') .append('<p> Event3 = ' + eval(ev3).toString() + ' </p>'); }); function fun_1() { var txt = 'text del missatge'; alert(txt); } |
1 2 3 4 | <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"> <body> </body> |
更改这些函数将允许您记录添加的侦听器:
1 2 3 4 | EventTarget.prototype.addEventListener EventTarget.prototype.attachEvent EventTarget.prototype.removeEventListener EventTarget.prototype.detachEvent |
与其他听众一起阅读
1 2 | console.log(someElement.onclick); console.log(someElement.getAttribute("onclick")); |
我最近正在处理事件,希望查看/控制页面中的所有事件。在研究了可能的解决方案之后,我决定采用自己的方式创建一个自定义系统来监视事件。所以,我做了三件事。
首先,我需要一个容器来容纳页面中的所有事件监听器:这是the
接下来,我创建了一个
最后,我扩展了本地的
用途:
1 2 3 4 5 | var bodyClickEvent = document.body.addEventListener("click", function () { console.log("body click"); }); // bodyClickEvent.remove(); |
1 2 | // EventListeners.get(document.body); // EventListeners.get("click"); |
演示
假设我们想了解当前页面中的每个事件侦听器。我们可以这样做(假设您使用的是脚本管理器扩展,在本例中是篡改)。以下脚本执行此操作:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | // ==UserScript== // @name New Userscript // @namespace http://tampermonkey.net/ // @version 0.1 // @description try to take over the world! // @author You // @include https://stackoverflow.com/* // @grant none // ==/UserScript== (function() { fetch("https://raw.githubusercontent.com/akinuri/js-lib/master/EventListener.js") .then(function (response) { return response.text(); }) .then(function (text) { eval(text); window.EventListeners = EventListeners; }); })(window); |
当我们列出所有的监听器时,它说有299个事件监听器。"似乎"有一些副本,但我不知道它们是否真的是副本。并非所有事件类型都是重复的,因此所有这些"重复"都可能是单个侦听器。
代码可以在我的存储库中找到。我不想把它贴在这里,因为它很长。
更新:这似乎不适用于jquery。当我检查EventListener时,我看到回调是
1 | function(b){return"undefined"!=typeof r&&r.event.triggered!==b.type?r.event.dispatch.apply(a,arguments):void 0} |
我相信这属于jquery,而不是实际的回调。jquery将实际回调存储在EventTarget的属性中:
1 2 3 | $(document.body).click(function () { console.log("jquery click"); }); |
要删除事件侦听器,需要将实际回调传递给