如何在调试或从JavaScript代码中找到DOM节点上的事件监听器?

时间:2022-03-10 00:07:47

I have a page where some event listeners are attached to input boxes and select boxes. Is there a way to find out which event listeners are observing a particular DOM node and for what event?

我有一个页面,其中一些事件监听器被附加到输入框和选择框中。是否有办法找出哪个事件监听器正在观察某个特定的DOM节点,以及观察哪个事件?

Events are attached using:

事件是在使用:

  1. Prototype's Event.observe;
  2. 原型的Event.observe;
  3. DOM's addEventListener;
  4. DOM的addEventListener;
  5. As element attribute element.onclick.
  6. 作为element.onclick元素属性。

16 个解决方案

#1


470  

If you just need to inspect what's happening on a page, you might try the Visual Event bookmarklet.

如果您只需要检查页面上正在发生的事情,您可以尝试Visual Event bookmarklet。

Update: Visual Event 2 available;

更新:Visual Event 2可用;

#2


344  

It depends on how the events are attached. For illustration presume we have the following click handler:

这取决于事件是如何关联的。假设我们有以下点击处理程序:

var handler = function() { alert('clicked!') };

We're going to attach it to our element using different methods, some which allow inspection and some that don't.

我们将使用不同的方法将它附加到我们的元素上,有些方法允许检查,有些则不允许。

Method A) single event handler

方法A)单个事件处理程序

element.onclick = handler;
// inspect
alert(element.onclick); // alerts "function() { alert('clicked!') }"

Method B) multiple event handlers

方法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

Method C): jQuery

方法C):jQuery

$(element).click(handler);
  • 1.3.x

    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 (stores the handler inside an object)

    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
    })
    

(See jQuery.fn.data and jQuery.data)

(见jQuery.fn。数据和jQuery.data)

Method D): Prototype (messy)

方法D):原型(混乱)

$(element).observe('click', handler);
  • 1.5.x

    1.5.x

    // inspect
    Event.observers.each(function(item) {
        if(item[0] == element) {
            alert(item[2]) // alerts "function() { alert('clicked!') }"
        }
    })
    
  • 1.6 to 1.6.0.3, inclusive (got very difficult here)

    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 (little better)

    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!') }"
    })
    

#3


198  

Chrome, Firefox, Vivaldi and Safari support getEventListeners(domElement) in their Developer Tools console.

Chrome、Firefox、Vivaldi和Safari在他们的开发工具控制台支持geteventlistener (domElement)。

For majority of the debugging purposes, this could be used.

对于大多数调试目的,这是可以使用的。

Below is a very good reference to use it: https://developers.google.com/chrome-developer-tools/docs/commandline-api#geteventlistenersobject

下面是使用它的一个很好的参考:https://developers.google.com/chrome-developer-tools/docs/commandline-api#geteventlistenersobject

#4


81  

WebKit Inspector in Chrome or Safari browsers now does this. It will display the event listeners for a DOM element when you select it in the Elements pane.

Chrome或Safari浏览器的WebKit检查器现在做到了这一点。当您在Elements窗格中选择DOM元素时,它将显示DOM元素的事件侦听器。

#5


58  

It is possible to list all event listeners in JavaScript: It's not that hard; you just have to hack the prototype's method of the HTML elements (before adding the listeners).

可以用JavaScript列出所有事件监听器:这并不难;您只需修改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});
};

Now every anchor element (a) will have a lastListenerInfo property wich contains all of its listeners. And it even works for removing listeners with anonymous functions.

现在每个锚元素(a)都有一个lastListenerInfo属性,它包含所有的侦听器。它甚至可以用匿名函数删除监听器。

#6


38  

(Rewriting the answer from this question since it's relevant here.)

(重写这个问题的答案,因为它在这里是相关的。)

When debugging, if you just want to see the events, I recommend either...

调试时,如果您只想查看事件,我建议您使用……

  1. Visual Event
  2. 视觉事件
  3. The Elements section of Chrome's Developer Tools: select an element and look for "Event Listeners" on the bottom right (similar in Firefox)
  4. Chrome开发工具的元素部分:选择一个元素,在右下角寻找“事件监听器”(Firefox中类似)

If you want to use the events in your code, and you are using jQuery before version 1.8, you can use:

如果您想在代码中使用事件,并且在1.8版本之前使用jQuery,您可以使用:

$(selector).data("events")

to get the events. As of version 1.8, using .data("events") is discontinued (see this bug ticket). You can use:

的事件。从版本1.8开始,使用.data(“events”)将停止(请参见此bug票据)。您可以使用:

$._data(element, "events")

Another example: Write all click events on a certain link to the console:

另一个示例:在到控制台的某个链接上写入所有单击事件:

var $myLink = $('a.myClass');
console.log($._data($myLink[0], "events").click);

(see http://jsfiddle.net/HmsQC/ for a working example)

(关于一个工作示例,请参见http://jsfiddle.net/HmsQC/)

Unfortunately, using $._data this is not recommended except for debugging since it is an internal jQuery structure, and could change in future releases. Unfortunately I know of no other easy means of accessing the events.

不幸的是,使用美元。_data这是不推荐的,除了调试之外,因为它是一个内部jQuery结构,并且可能在以后的版本中更改。不幸的是,我不知道还有什么其他简单的方法可以访问这些事件。

#7


26  

Use getEventListeners in Google Chrome:

使用geteventlistener在谷歌Chrome中:

getEventListeners(document.getElementByID('btnlogin'));
getEventListeners($('#btnlogin'));

#8


22  

1: Prototype.observe uses Element.addEventListener (see the source code)

1:原型。观察使用元素。addEventListener(参见源代码)

2: You can override Element.addEventListener to remember the added listeners (handy property EventListenerList was removed from DOM3 spec proposal). Run this code before any event is attached:

2:你可以重写元素。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);
  };
})();

Read all the events by:

阅读所有活动:

var clicks = someElement.eventListenerList.click;
if(clicks) clicks.forEach(function(f) {
  alert("I listen to this function: "+f.toString());
});

And don't forget to override Element.removeEventListener to remove the event from the custom Element.eventListenerList.

不要忘记重写元素。removeEventListener将事件从自定义Element.eventListenerList中删除。

3: the Element.onclick property needs special care here:

3:元素。onclick属性需要特别注意:

if(someElement.onclick)
  alert("I also listen tho this: "+someElement.onclick.toString());

4: don't forget the Element.onclick content attribute: these are two different things:

4:不要忘记元素。onclick内容属性:这是两个不同的东西:

someElement.onclick = someHandler; // IDL attribute
someElement.setAttribute("onclick","otherHandler(event)"); // content attribute

So you need to handle it, too:

所以你也需要处理它:

var click = someElement.getAttribute("onclick");
if(click) alert("I even listen to this: "+click);

The Visual Event bookmarklet (mentioned in the most popular answer) only steals the custom library handler cache:

Visual Event bookmarklet(在最流行的答案中提到)只窃取自定义库处理程序缓存:

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).

事实证明,W3C推荐的DOM接口并没有提供任何标准方法来查找将哪些事件侦听器附加到特定元素上。虽然这似乎是一个疏忽,但是有人提议将名为eventListenerList的属性包含到第3级DOM规范中,但不幸的是,在后来的草案中被删除了。因此,我们不得不查看各个Javascript库,它们通常维护附加事件的缓存(以便以后可以删除它们并执行其他有用的抽象)。

As such, in order for Visual Event to show events, it must be able to parse the event information out of a Javascript library.

因此,为了让Visual Event显示事件,它必须能够从Javascript库中解析事件信息。

Element overriding may be questionable (i.e. because there are some DOM specific features like live collections, which can not be coded in JS), but it gives the eventListenerList support natively and it works in Chrome, Firefox and Opera (doesn't work in IE7).

元素重写可能是有问题的(例如,有一些特定于DOM的特性,比如live collections,不能用JS编写),但是它本身就提供了eventListenerList支持,并且可以在Chrome、Firefox和Opera中使用(在IE7中不能使用)。

#9


21  

You could wrap the native DOM methods for managing event listeners by putting this at the top of your <head>:

您可以在 >的顶部包装用于管理事件监听器的本地DOM方法:

<script>
    (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);
</script>

H/T @les2

H / T @les2

#10


16  

The Firefox developer tools now does this. Events are shown by clicking the "ev" button on the right of each element's display, including jQuery and DOM events.

Firefox开发工具现在就这么做了。事件通过单击每个元素显示右边的“ev”按钮来显示,包括jQuery和DOM事件。

如何在调试或从JavaScript代码中找到DOM节点上的事件监听器?

#11


12  

If you have Firebug, you can use console.dir(object or array) to print a nice tree in the console log of any JavaScript scalar, array, or object.

如果您有Firebug,可以使用控制台。在任何JavaScript标量、数组或对象的控制台日志中打印一个漂亮的树。

Try:

试一试:

console.dir(clickEvents);

or

console.dir(window);

#12


7  

Opera 12 (not the latest Chrome Webkit engine based) Dragonfly has had this for a while and is obviously displayed in the DOM structure. In my opinion it is a superior debugger and is the only reason remaining why I still use the Opera 12 based version (there is no v13, v14 version and the v15 Webkit based lacks Dragonfly still)

Opera 12(不是基于Chrome Webkit引擎的最新版本)蜻蜓已经有一段时间了,并且很明显地显示在DOM结构中。在我看来,它是一个优秀的调试器,也是为什么我仍然使用Opera 12的版本(没有v13、v14版本和基于v15的Webkit的v15版本)的唯一原因。

如何在调试或从JavaScript代码中找到DOM节点上的事件监听器?

#13


5  

Fully working solution based on answer by Jan Turon - behaves like getEventListeners() from console:

根据Jan Turon的回答,完整的工作解决方案——就像来自控制台的geteventlistener ():

(There is a little bug with duplicates. It doesn't break much anyway.)

(有一个带副本的小错误。它不会碎很多)

(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];
  };
})();

Usage:

用法:

someElement.getEventListeners([name]) - return list of event listeners, if name is set return array of listeners for that event

geteventlistener ([name])——返回事件监听器的列表,如果名称被设置为该事件的监听器返回数组

someElement.clearEventListeners([name]) - remove all event listeners, if name is set only remove listeners for that event

cleareventlistener ([name])——删除所有事件监听器,如果名称设置为name,则只删除该事件的监听器

#14


4  

Prototype 1.7.1 way

原型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];
}

#15


2  

I am trying to do that in jQuery 2.1, and with the "$().click() -> $(element).data("events").click;" method it doesn't work.

我在jQuery 2.1中尝试这样做,并使用“$().click() -> $(元素).data(“事件”).click;“方法不起作用”。

I realized that only the $._data() functions works in my case :

我意识到,在我的案例中,只有$._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>

#16


1  

There exists nice jQuery Events extension :

有很好的jQuery事件扩展:

如何在调试或从JavaScript代码中找到DOM节点上的事件监听器? (topic source)

(主题)

#1


470  

If you just need to inspect what's happening on a page, you might try the Visual Event bookmarklet.

如果您只需要检查页面上正在发生的事情,您可以尝试Visual Event bookmarklet。

Update: Visual Event 2 available;

更新:Visual Event 2可用;

#2


344  

It depends on how the events are attached. For illustration presume we have the following click handler:

这取决于事件是如何关联的。假设我们有以下点击处理程序:

var handler = function() { alert('clicked!') };

We're going to attach it to our element using different methods, some which allow inspection and some that don't.

我们将使用不同的方法将它附加到我们的元素上,有些方法允许检查,有些则不允许。

Method A) single event handler

方法A)单个事件处理程序

element.onclick = handler;
// inspect
alert(element.onclick); // alerts "function() { alert('clicked!') }"

Method B) multiple event handlers

方法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

Method C): jQuery

方法C):jQuery

$(element).click(handler);
  • 1.3.x

    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 (stores the handler inside an object)

    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
    })
    

(See jQuery.fn.data and jQuery.data)

(见jQuery.fn。数据和jQuery.data)

Method D): Prototype (messy)

方法D):原型(混乱)

$(element).observe('click', handler);
  • 1.5.x

    1.5.x

    // inspect
    Event.observers.each(function(item) {
        if(item[0] == element) {
            alert(item[2]) // alerts "function() { alert('clicked!') }"
        }
    })
    
  • 1.6 to 1.6.0.3, inclusive (got very difficult here)

    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 (little better)

    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!') }"
    })
    

#3


198  

Chrome, Firefox, Vivaldi and Safari support getEventListeners(domElement) in their Developer Tools console.

Chrome、Firefox、Vivaldi和Safari在他们的开发工具控制台支持geteventlistener (domElement)。

For majority of the debugging purposes, this could be used.

对于大多数调试目的,这是可以使用的。

Below is a very good reference to use it: https://developers.google.com/chrome-developer-tools/docs/commandline-api#geteventlistenersobject

下面是使用它的一个很好的参考:https://developers.google.com/chrome-developer-tools/docs/commandline-api#geteventlistenersobject

#4


81  

WebKit Inspector in Chrome or Safari browsers now does this. It will display the event listeners for a DOM element when you select it in the Elements pane.

Chrome或Safari浏览器的WebKit检查器现在做到了这一点。当您在Elements窗格中选择DOM元素时,它将显示DOM元素的事件侦听器。

#5


58  

It is possible to list all event listeners in JavaScript: It's not that hard; you just have to hack the prototype's method of the HTML elements (before adding the listeners).

可以用JavaScript列出所有事件监听器:这并不难;您只需修改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});
};

Now every anchor element (a) will have a lastListenerInfo property wich contains all of its listeners. And it even works for removing listeners with anonymous functions.

现在每个锚元素(a)都有一个lastListenerInfo属性,它包含所有的侦听器。它甚至可以用匿名函数删除监听器。

#6


38  

(Rewriting the answer from this question since it's relevant here.)

(重写这个问题的答案,因为它在这里是相关的。)

When debugging, if you just want to see the events, I recommend either...

调试时,如果您只想查看事件,我建议您使用……

  1. Visual Event
  2. 视觉事件
  3. The Elements section of Chrome's Developer Tools: select an element and look for "Event Listeners" on the bottom right (similar in Firefox)
  4. Chrome开发工具的元素部分:选择一个元素,在右下角寻找“事件监听器”(Firefox中类似)

If you want to use the events in your code, and you are using jQuery before version 1.8, you can use:

如果您想在代码中使用事件,并且在1.8版本之前使用jQuery,您可以使用:

$(selector).data("events")

to get the events. As of version 1.8, using .data("events") is discontinued (see this bug ticket). You can use:

的事件。从版本1.8开始,使用.data(“events”)将停止(请参见此bug票据)。您可以使用:

$._data(element, "events")

Another example: Write all click events on a certain link to the console:

另一个示例:在到控制台的某个链接上写入所有单击事件:

var $myLink = $('a.myClass');
console.log($._data($myLink[0], "events").click);

(see http://jsfiddle.net/HmsQC/ for a working example)

(关于一个工作示例,请参见http://jsfiddle.net/HmsQC/)

Unfortunately, using $._data this is not recommended except for debugging since it is an internal jQuery structure, and could change in future releases. Unfortunately I know of no other easy means of accessing the events.

不幸的是,使用美元。_data这是不推荐的,除了调试之外,因为它是一个内部jQuery结构,并且可能在以后的版本中更改。不幸的是,我不知道还有什么其他简单的方法可以访问这些事件。

#7


26  

Use getEventListeners in Google Chrome:

使用geteventlistener在谷歌Chrome中:

getEventListeners(document.getElementByID('btnlogin'));
getEventListeners($('#btnlogin'));

#8


22  

1: Prototype.observe uses Element.addEventListener (see the source code)

1:原型。观察使用元素。addEventListener(参见源代码)

2: You can override Element.addEventListener to remember the added listeners (handy property EventListenerList was removed from DOM3 spec proposal). Run this code before any event is attached:

2:你可以重写元素。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);
  };
})();

Read all the events by:

阅读所有活动:

var clicks = someElement.eventListenerList.click;
if(clicks) clicks.forEach(function(f) {
  alert("I listen to this function: "+f.toString());
});

And don't forget to override Element.removeEventListener to remove the event from the custom Element.eventListenerList.

不要忘记重写元素。removeEventListener将事件从自定义Element.eventListenerList中删除。

3: the Element.onclick property needs special care here:

3:元素。onclick属性需要特别注意:

if(someElement.onclick)
  alert("I also listen tho this: "+someElement.onclick.toString());

4: don't forget the Element.onclick content attribute: these are two different things:

4:不要忘记元素。onclick内容属性:这是两个不同的东西:

someElement.onclick = someHandler; // IDL attribute
someElement.setAttribute("onclick","otherHandler(event)"); // content attribute

So you need to handle it, too:

所以你也需要处理它:

var click = someElement.getAttribute("onclick");
if(click) alert("I even listen to this: "+click);

The Visual Event bookmarklet (mentioned in the most popular answer) only steals the custom library handler cache:

Visual Event bookmarklet(在最流行的答案中提到)只窃取自定义库处理程序缓存:

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).

事实证明,W3C推荐的DOM接口并没有提供任何标准方法来查找将哪些事件侦听器附加到特定元素上。虽然这似乎是一个疏忽,但是有人提议将名为eventListenerList的属性包含到第3级DOM规范中,但不幸的是,在后来的草案中被删除了。因此,我们不得不查看各个Javascript库,它们通常维护附加事件的缓存(以便以后可以删除它们并执行其他有用的抽象)。

As such, in order for Visual Event to show events, it must be able to parse the event information out of a Javascript library.

因此,为了让Visual Event显示事件,它必须能够从Javascript库中解析事件信息。

Element overriding may be questionable (i.e. because there are some DOM specific features like live collections, which can not be coded in JS), but it gives the eventListenerList support natively and it works in Chrome, Firefox and Opera (doesn't work in IE7).

元素重写可能是有问题的(例如,有一些特定于DOM的特性,比如live collections,不能用JS编写),但是它本身就提供了eventListenerList支持,并且可以在Chrome、Firefox和Opera中使用(在IE7中不能使用)。

#9


21  

You could wrap the native DOM methods for managing event listeners by putting this at the top of your <head>:

您可以在 >的顶部包装用于管理事件监听器的本地DOM方法:

<script>
    (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);
</script>

H/T @les2

H / T @les2

#10


16  

The Firefox developer tools now does this. Events are shown by clicking the "ev" button on the right of each element's display, including jQuery and DOM events.

Firefox开发工具现在就这么做了。事件通过单击每个元素显示右边的“ev”按钮来显示,包括jQuery和DOM事件。

如何在调试或从JavaScript代码中找到DOM节点上的事件监听器?

#11


12  

If you have Firebug, you can use console.dir(object or array) to print a nice tree in the console log of any JavaScript scalar, array, or object.

如果您有Firebug,可以使用控制台。在任何JavaScript标量、数组或对象的控制台日志中打印一个漂亮的树。

Try:

试一试:

console.dir(clickEvents);

or

console.dir(window);

#12


7  

Opera 12 (not the latest Chrome Webkit engine based) Dragonfly has had this for a while and is obviously displayed in the DOM structure. In my opinion it is a superior debugger and is the only reason remaining why I still use the Opera 12 based version (there is no v13, v14 version and the v15 Webkit based lacks Dragonfly still)

Opera 12(不是基于Chrome Webkit引擎的最新版本)蜻蜓已经有一段时间了,并且很明显地显示在DOM结构中。在我看来,它是一个优秀的调试器,也是为什么我仍然使用Opera 12的版本(没有v13、v14版本和基于v15的Webkit的v15版本)的唯一原因。

如何在调试或从JavaScript代码中找到DOM节点上的事件监听器?

#13


5  

Fully working solution based on answer by Jan Turon - behaves like getEventListeners() from console:

根据Jan Turon的回答,完整的工作解决方案——就像来自控制台的geteventlistener ():

(There is a little bug with duplicates. It doesn't break much anyway.)

(有一个带副本的小错误。它不会碎很多)

(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];
  };
})();

Usage:

用法:

someElement.getEventListeners([name]) - return list of event listeners, if name is set return array of listeners for that event

geteventlistener ([name])——返回事件监听器的列表,如果名称被设置为该事件的监听器返回数组

someElement.clearEventListeners([name]) - remove all event listeners, if name is set only remove listeners for that event

cleareventlistener ([name])——删除所有事件监听器,如果名称设置为name,则只删除该事件的监听器

#14


4  

Prototype 1.7.1 way

原型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];
}

#15


2  

I am trying to do that in jQuery 2.1, and with the "$().click() -> $(element).data("events").click;" method it doesn't work.

我在jQuery 2.1中尝试这样做,并使用“$().click() -> $(元素).data(“事件”).click;“方法不起作用”。

I realized that only the $._data() functions works in my case :

我意识到,在我的案例中,只有$._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>

#16


1  

There exists nice jQuery Events extension :

有很好的jQuery事件扩展:

如何在调试或从JavaScript代码中找到DOM节点上的事件监听器? (topic source)

(主题)