我有一个页面,其中一些事件监听器附加到输入框和选择框。是否有一种方法可以找出哪些事件侦听器正在观察特定的DOM节点以及观察什么事件?
使用以下方法附加事件:
Prototype, Event.observe; 唐,addEventListener; 元素属性元素onclick
我有一个页面,其中一些事件监听器附加到输入框和选择框。是否有一种方法可以找出哪些事件侦听器正在观察特定的DOM节点以及观察什么事件?
使用以下方法附加事件:
Prototype, Event.observe; 唐,addEventListener; 元素属性元素onclick
当前回答
Chrome, Firefox, Vivaldi和Safari在他们的开发人员工具控制台中支持getEventListeners(domElement)。
对于大多数调试目的,都可以使用这种方法。
下面是一个很好的使用它的参考: getEventListeners函数
Clifford Fajardo在评论中给出了高度投票的建议:
getEventListeners($0)将获得你在Chrome开发工具中关注的元素的事件监听器。
其他回答
我试图在jQuery 2.1中做到这一点,并使用“$().click() -> $(element).data(“events”).click;”方法它不起作用。
我意识到只有$._data()函数在我的情况下工作:
$(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); } <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <body> </body>
完全工作的解决方案基于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<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];
};
})();
用法:
someElement.getEventListeners([name]) -返回事件监听器列表,如果设置了name则返回该事件的监听器数组
someElement.clearEventListeners([name]) -删除所有事件监听器,如果设置了name,则只删除该事件的监听器
这取决于事件是如何附加的。为了说明,假设我们有以下点击处理程序:
var handler = function() { alert('clicked!') };
我们将使用不同的方法将它附加到元素上,有些允许检查,有些不允许。
方法A)单个事件处理程序
element.onclick = handler;
// inspect
console.log(element.onclick); // "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) { console.log(value) // "function() { alert('clicked!') }" }) 1.4.x (stores the handler inside an object) // inspect var clickEvents = $(element).data("events").click; jQuery.each(clickEvents, function(key, handlerObj) { console.log(handlerObj.handler) // "function() { alert('clicked!') }" // also available: handlerObj.type, handlerObj.namespace }) 1.7+ (very nice) Made using knowledge from this comment. events = $._data(this, 'events'); for (type in events) { events[type].forEach(function (event) { console.log(event['handler']); }); }
(参见jQuery.fn.data和jQuery.data)
方法D):原型(凌乱)
$(element).observe('click', handler);
1.5.x // inspect Event.observers.each(function(item) { if(item[0] == element) { console.log(item[2]) // "function() { alert('clicked!') }" } }) 1.6 to 1.6.0.3, inclusive (got very difficult here) // 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){ console.log(wrapper.handler) // "function() { alert('clicked!') }" }) 1.6.1 (little better) // inspect var clickEvents = element.getStorage().get('prototype_event_registry').get('click'); clickEvents.each(function(wrapper){ console.log(wrapper.handler) // "function() { alert('clicked!') }" })
当单击控制台中的结果输出(其中显示了函数的文本)时,控制台将直接导航到相关JS文件中函数声明的行。
使用getEventListeners在谷歌Chrome:
getEventListeners(document.getElementByID('btnlogin'));
getEventListeners($('#btnlogin'));
原型1.7.1方式
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];
}