如何在JavaScript或调试中在DOM节点上查找事件侦听器?

How to find event listeners on a DOM node in JavaScript or in debugging?

提问人:Navneet 提问时间:1/15/2009 最后编辑:BBaysingerNavneet 更新时间:10/3/2023 访问量:904018

问:

我有一个页面,其中一些事件侦听器附加到输入框和选择框。有没有办法找出哪些事件侦听器正在观察特定的 DOM 节点以及针对什么事件?

使用以下方法附加事件:

  1. 原型的 Event.observe;
  2. DOM的addEventListener;
  3. 作为元素属性。element.onclick
JavaScript 事件 DOM

评论

3赞 Crescent Fresh 1/15/2009
首先,事件是如何附加的?您是否正在使用库(例如Prototype,jQuery等)?
0赞 Braden Best 5/11/2017
需要注意的是,可以通过 为相同类型的事件附加多个回调函数,而每次分配时都会覆盖。element.addEventListener(type, callback, [bubble])element.onclick = function
6赞 Gabriel Petersson 7/22/2020
获取所有事件及其各自的元素:Array.from(document.querySelectorAll("*")).forEach(e => { const ev = getEventListeners(e); if (Object.keys(ev).length !== 0) {console.log(e, ev)} })
0赞 John Henckel 10/22/2020
您可以劫持 DOM 元素中所有侦听器的列表并捕获该列表。下面是示例代码 stackoverflow.com/a/64484951/1812732addEventListener

答:

398赞 Crescent Fresh 1/15/2009 #1

这取决于事件的附加方式。为了说明这一点,假设我们有以下点击处理程序:

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(将处理程序存储在对象中)

     // 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+ (非常好)

    利用此评论中的知识制作。

     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 到 1.6.0.3,包括 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){
         console.log(wrapper.handler) // "function() { alert('clicked!') }"
     })
    
  • 1.6.1(稍微好一点)

     // inspect
     var clickEvents = element.getStorage().get('prototype_event_registry').get('click');
     clickEvents.each(function(wrapper){
         console.log(wrapper.handler) // "function() { alert('clicked!') }"
     })
    

在控制台中单击生成的输出(显示函数的文本)时,控制台将直接导航到相关 JS 文件中函数声明的行。

评论

4赞 Keith Bentrup 9/15/2009
感谢您更新此内容。不幸的是,您必须遍历每种类型的处理程序。
4赞 Nickolay 10/19/2011
在“方法 B”(addEventListener)上,以下是关于使用纯 DOM 事件 API 注册的处理程序的枚举工具状态的答案:stackoverflow.com/questions/7810534/...
0赞 Crescent Fresh 4/25/2012
@John:感谢您的评论。你有一个“真正的JavaScript”的例子来获取以前通过?addEventListener
7赞 tomdemuyt 5/31/2012
@Jan,这似乎不适用于 jQuery 1.7.2,该版本是否有不同的方法?
18赞 Matt Browne 2/14/2014
@tomdemuyt 在jQuery中,事件现在存储在内部数据数组中,而不是像以前那样通过访问。要访问内部事件数据,请使用 。请注意,此函数在 jQuery 源代码中被标记为“仅供内部使用”,因此不保证它将来会一直有效,但我相信它从 jQuery 1.7 开始就一直有效并且仍然有效。.data('events')$._data(elem, 'events')
13赞 Michael Butler 1/8/2010 #2

如果你有 Firebug,你可以用来在任何 JavaScript 标量、数组或对象的控制台日志中打印一个漂亮的树。console.dir(object or array)

尝试:

console.dir(clickEvents);

console.dir(window);

评论

9赞 Javier Constanzo 8/31/2013
firebug 1.12 getfirebug.com/wiki/index.php/GetEventListeners 中的新功能
541赞 Andrew Hedges 8/7/2010 #3

如果您只需要检查页面上发生的情况,则可以尝试使用视觉事件书签。

更新Visual Event 2 可用。

评论

3赞 Robin Maben 9/15/2011
完善!击败 Firebug 的插件。EventBug
34赞 Tony R 3/9/2012
这将向页面添加数以百万计的元素,其中许多是图像。在具有许多事件处理程序的页面上,它的实用性大大降低(我的有 17k,而 Visual Event 需要大约 3 分钟才能加载)。
16赞 kmote 2/18/2013
我相信@ssharma提到的Chrome扩展程序是这里提供的
1赞 hiway 11/19/2013
如果页面引用了第三方 js 库,则 Visial Event 不起作用。它引发错误:XMLHttpRequest 无法加载 A.com/js/jquery-ui-1.10.3.custom.js?_=1384831682813。Access-Control-Allow-Origin 不允许源 B.com
12赞 oriadam 12/31/2015
Chrome 和 FF 内部开发者工具 (F12) 有一个内置的事件查看器!Chrome:在“元素”选项卡上,选择 和 元素,然后看到右侧有:样式、计算、事件侦听器
98赞 Ishan 1/17/2011 #4

Chrome 或 Safari 浏览器中的 WebKit Inspector 现在可以执行此操作。当您在“元素”窗格中选择 DOM 元素时,它将显示该元素的事件侦听器。

评论

9赞 huyz 7/25/2011
我不确定它是否显示了所有事件处理程序;只是单个 HTML 事件处理程序。
3赞 Nickolay 10/19/2011
我应该提到 Firebug 的 EventBug 插件,以实现完整性<softwareishard.com/blog/category/eventbug>
0赞 siliconrockstar 12/20/2013
这让我很开心,一些遗留的原型代码将多个函数绑定到同一元素上的同一事件,我迫不及待地想追踪它们。非常感谢伊山。
0赞 Merchako 1/15/2023
这是一个繁忙的界面。您能告诉我们这些在窗格中的显示位置吗?
90赞 Ivan Castellanos 6/22/2011 #5

可以在 JavaScript 中列出所有事件侦听器: 这并不难;您只需要破解 HTML 元素的方法(在添加侦听器之前)。prototype

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

现在,每个锚元素 () 都有一个包含其所有侦听器的属性。它甚至可以删除具有匿名功能的侦听器。alastListenerInfo

评论

9赞 huyz 7/25/2011
如果您正在编写用户脚本或内容脚本,则此方法将不起作用。如今,不仅可能被沙盒化,而且您如何保证执行顺序?
13赞 Esailija 6/16/2012
你不能修改一下吗?无论如何,这就是继承的地方。Node.prototypeHTMLAnchorElement.addEventListener
5赞 RobG 11/13/2012
您假设用户代理实现了 DOM 主机对象的原型继承,并允许您修改它们。这些都不是好主意:不要修改你不拥有的对象
1赞 gotofritz 9/15/2015
这是非常无用的 - 它显示了添加了哪些 eventListeners,这在某些情况下可能很好,但不能显示删除了什么。因此,如果您尝试调试已删除的内容和未删除的内容,则根本没有办法。
1赞 Ivan Castellanos 2/21/2016
@doABarrelRoll721我想知道你是否有常识。你看,JavaScript 在浏览器的一侧执行,所以你可以随时执行它,例如,在 tamper-monkey 的帮助下,你可以在你打开的所有网站上执行。
1赞 doABarrelRoll721 2/21/2016
@IvanCastellanos我的意思是你的lastListenerInfo数组只包含添加的侦听器。OP 询问哪些事件侦听器正在观察特定的 DOM 节点,其中包括被删除的节点。如果你要覆盖你对lastListenerInfo数组所做的相同,那么它就会完全符合OP的要求(尽管他说的是输入和选择元素,而不是锚点,而是其他什么)。removeEventListeneraddEventListener
46赞 Luke 10/23/2012 #6

(重写这个问题的答案,因为它与此处相关。

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

  1. 视觉事件
  2. 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赞 Marius Gedminas 12/6/2013
$._data(elem, "events")似乎不适用于 jQuery 1.10,至少对于使用 .有谁知道如何调试这些?$(elem).on('event', ...)
4赞 Luke 12/7/2013
我不是肯定的,但我认为第一个参数可能需要是一个元素而不是jQuery对象。所以我需要将上面的例子修复为$._dataconsole.log($._data($myLink[0], "events").click);
5赞 Ronald 1/18/2013 #7

原型 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];
}
640赞 Raghav 5/14/2013 #8

Chrome、Vivaldi 和 Safari 在其开发者工具控制台中提供支持。getEventListeners(domElement)

对于大多数调试目的,可以使用此功能。

下面是一个很好的使用它的参考:
getEventListeners 函数


克利福德·法哈多(Clifford Fajardo)在评论中高度投票的提示:

getEventListeners($0)将获取您在 Chrome 开发工具中关注的元素的事件侦听器。

评论

18赞 gillyspy 12/21/2013
不错,但仅适用于 Chrome 控制台的命令行:(
8赞 jave.web 3/16/2015
@Raghav啊,谢谢,用法是 getEventListeners(object) NOT:正如我最初认为的那样:)obj getEventListeners()
31赞 doABarrelRoll721 2/20/2016
如果您能解释如何获取事件侦听器的源代码,您可以为我节省 3 个小时。这个“参考”没有解释任何事情。如果其他人蒙受损失,方法如下: .将“焦点”更改为要检查的事件,如果同一事件上有多个侦听器,则将“焦点”更改为数字。var list = getEventListeners(document.getElementById("YOURIDHERE")); console.log(list["focus"][0]["listener"].toString())
109赞 Clifford Fajardo 2/1/2017
提示:将获取您在 Chrome 开发工具中关注的元素的事件侦听器。我一直在用这个。喜欢不必使用 querySelector 或 get__By_ 函数getEventListeners($0)
14赞 Kevinoid 1/4/2022
不幸的是,虽然 Firebug 支持它,但 Firefox 开发者工具不支持它。(错误1164285getEventListeners())
10赞 Daniel Sokolowski 11/29/2013 #9

Opera 12(不是最新的基于 Chrome Webkit 引擎)Dragonfly 已经有一段时间了,并且显然显示在 DOM 结构中。在我看来,它是一个出色的调试器,也是我仍然使用基于 Opera 12 的版本的唯一原因(没有 v13、v14 版本,基于 v15 Webkit 仍然缺少 Dragonfly)

enter image description here

63赞 Pranay Soni 3/19/2014 #10

Google Chrome 中使用 getEventListeners:

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

评论

9赞 Bryan Grace 11/19/2015
未捕获的 ReferenceError:未定义 getEventListeners
12赞 Nickolay 2/13/2016
getEventListeners 仅适用于 Chrome 的 devtools 控制台。这是这个更详细的答案的副本:stackoverflow.com/a/16544813/1026
36赞 Jan Turoň 4/3/2014 #11

1:使用 Element.addEventListener(参见源码Prototype.observe)

2:您可以覆盖以记住添加的侦听器(方便的属性已从 DOM3 规范提案中删除)。在附加任何事件之前运行此代码:Element.addEventListenerEventListenerList

(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.removeEventListenerElement.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 书签(在最流行的答案中提到)仅窃取自定义库处理程序缓存:

事实证明,W3C 没有提供标准方法 推荐 DOM 接口,找出事件监听器是什么 附加到特定元素。虽然这似乎是一个 监督,有一个提议包括一个名为 eventListenerList 设置为 3 级 DOM 规范,但 不幸的是,在后来的草案中被删除了。因此,我们被迫 查看了各个 Javascript 库,这些库通常 维护附加事件的缓存(以便以后可以删除它们,并且 执行其他有用的抽象)。

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

元素覆盖可能是有问题的(即因为有一些特定于 DOM 的功能,如实时集合,不能用 JS 编码),但它原生提供了 eventListenerList 支持,并且适用于 Chrome、Firefox 和 Opera(在 IE7 中不起作用)。

19赞 simonzack 1/14/2015 #12

Firefox 开发者工具现在可以做到这一点。通过单击每个元素显示右侧的“ev”按钮来显示事件,包括 jQueryDOM 事件。

Screenshot of Firefox developer tools' event listener button in the inspector tab

评论

0赞 Eric 2/4/2015
我确实查看了 Visual Event 2 书签显示连接到的事件的页面上的一个 dom 元素,并且我确实看到了右侧的小“ev”按钮,就像您显示的那样。
0赞 Nick Tsai 8/4/2017
Firefox 的事件侦听器可以找出 jQuery 委托的事件,而 Chrome 需要插件来做到这一点。
5赞 Joel Barba 5/19/2015 #13

我正在尝试在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>

评论

0赞 meetar 4/2/2022
这对我有用!但是 TypeScript 抱怨说“属性'_data'在类型'JQueryStatic'上不存在。你是说'数据'吗?这是怎么回事?
13赞 n00b 6/27/2015 #14

基于 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 only 删除该事件的侦听器

评论

3赞 David Bradshaw 8/25/2015
这是一个很好的答案,但我无法让它在 和 元素上工作。bodydocument
2赞 Stefan Steiger 7/21/2018
@David Bradshaw:因为正文、文档和窗口都有自己的原型,而不是 Element 原型......
1赞 Stefan Steiger 7/23/2018
@n00b:有一个bug。这就是为什么嗯。在 listener 的 if 语句中使用逗号运算符,并使用 useCaption...逗号运算符计算其每个操作数(从左到右)并返回最后一个操作数的值。因此,无论事件的类型如何,您都会删除在 useCapture 中匹配的第一个 eventListener...那应该是&&而不是逗号。
1赞 Adam Katz 8/20/2022
需要明确的是,这重新定义了 Element.prototype.addEventListener,因此必须在进行任何此类调用之前运行。这意味着用户脚本不能使用它来与网站的听众进行交互。
25赞 jrz 11/7/2015 #15

你可以包装用于管理事件侦听器的原生 DOM 方法,方法是将其放在 :<head>

<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

评论

0赞 Maciej Krawczyk 2/4/2017
如果我错了,请纠正我,但这不是仅适用于附加到窗口的事件侦听器吗?
0赞 jrz 2/7/2017
@MaciejKrawczyk是的,还有那些冒泡的人
3赞 T.Todua 2/28/2017 #16

存在不错的jQuery事件扩展

enter image description here(主题来源)

5赞 akinuri 6/28/2018 #17

我最近在处理事件,并希望查看/控制页面中的所有事件。在研究了可能的解决方案后,我决定走自己的路,创建一个自定义系统来监控事件。所以,我做了三件事。

首先,我需要一个容器来容纳页面中的所有事件侦听器:这就是对象。它有三种有用的方法:、 和 。EventListenersadd()remove()get()

接下来,我创建了一个对象来保存事件的必要信息,即:、、、、、,并添加了一个删除侦听器的方法。EventListenertargettypecallbackoptionsuseCapturewantsUntrustedremove()

最后,我扩展了原生 和 方法,使它们与我创建的对象 ( 和 ) 一起使用。addEventListener()removeEventListener()EventListenerEventListeners

用法:

var bodyClickEvent = document.body.addEventListener("click", function () {
    console.log("body click");
});

// bodyClickEvent.remove();

addEventListener()创建一个对象,将其添加到该对象并返回该对象,以便以后可以将其删除。EventListenerEventListenersEventListener

EventListeners.get()可用于查看页面中的侦听器。它接受 或 字符串(事件类型)。EventTarget

// EventListeners.get(document.body);
// EventListeners.get("click");

演示

假设我们想知道当前页面中的每个事件侦听器。我们可以做到这一点(假设您使用的是脚本管理器扩展,在本例中为 Tampermonkey)。以下脚本执行此操作:

// ==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/event/event-listeners/event-listeners.js")
        .then(function (response) {
            return response.text();
        })
        .then(function (text) {
            eval(text);
            window.EventListeners = EventListeners;
        });
})(window);

当我们列出所有侦听器时,它说有 299 个事件侦听器。“似乎”有一些重复,但我不知道它们是否真的是重复的。并非每个事件类型都是重复的,因此所有这些“重复”都可能是单个侦听器。

screenshot of console listing all event listeners in this page

代码可以在我的存储库中找到。我不想在这里发布它,因为它很长。


更新:这似乎不适用于jQuery。当我检查 EventListener 时,我看到回调是

function(b){return"undefined"!=typeof r&&r.event.triggered!==b.type?r.event.dispatch.apply(a,arguments):void 0}

我相信这属于jQuery,而不是实际的回调。jQuery 将实际回调存储在 EventTarget 的属性中:

$(document.body).click(function () {
    console.log("jquery click");
});

enter image description here

若要删除事件侦听器,需要将实际回调传递给该方法。因此,为了使它与jQuery一起工作,它需要进一步修改。我将来可能会解决这个问题。removeEventListener()

2赞 Aiden Waterman 4/18/2019 #18

更改这些函数将允许您记录添加的侦听器:

EventTarget.prototype.addEventListener
EventTarget.prototype.attachEvent
EventTarget.prototype.removeEventListener
EventTarget.prototype.detachEvent

读取其余侦听器

console.log(someElement.onclick);
console.log(someElement.getAttribute("onclick"));
26赞 Gabriel Petersson 7/22/2020 #19

粘贴到控制台中以将所有内容打印在其 HTML 元素旁边eventListeners

Array.from(document.querySelectorAll("*")).forEach(element => {
    const events = getEventListeners(element)
    if (Object.keys(events).length !== 0) {
         console.log(element, events)
    }
})

评论

0赞 klm123 9/14/2021
also const ev = getEventListeners(document) if (Object.keys(ev).length !== 0) console.log(ev)
3赞 Ben 4/21/2022
如果我尝试在我的 JS 文件中使用,我会得到 Uncaught ReferenceError: getEventListeners is not defined。getEventListeners
1赞 Gabriel Petersson 4/22/2022
@Ben,因为您的 JS 不知道您将在 Chrome 上下文中运行代码。切勿在生产中使用它,仅用于调试目的
14赞 aljgom 9/5/2022 #20

2022年更新:

在 中,有一个选项卡,您可以在其中查看元素的侦听器。Chrome Developer ToolsElements panelEvent Listeners

您也可以取消选择“祖先”,以便它仅显示该元素的侦听器

Developer Tools

3赞 Akaisteph7 9/29/2023 #21

目前,2023 年 9 月,在 Firefox 浏览器 117.0.1 中,您可以通过单击“开发者工具”中“检查器”中的相应“事件”按钮来查看此内容,如下所示:

enter image description here

1赞 MoonLite 10/3/2023 #22

要快速列出和/或删除文档或任何元素上的所有事件处理程序:

(仅适用于 Chrome 控制台,因为它使用 ,请参阅:
https://developer.chrome.com/docs/devtools/console/utilities/#getEventListeners-function
getEventListeners()
)

let list = [];
let targets = Array.from(document.querySelectorAll('*'));
targets.push(document);
targets.forEach((obj) => {
    let listeners = getEventListeners(obj);
    for (p in listeners) {
        listeners[p].forEach((l) => {
            removeEventListener(l.type, l.listener, l.useCapture);
            list.push([obj, l.type, l.listener, '' + l.listener, l.useCapture]);
        });
    }
});
console.table(list);


或键入控制台(或代码):

debugger;

单步执行代码以查找例如将鼠标悬停在元素上时究竟发生了什么。

debugger;也非常适合停止停止任何失控的循环。


稍微相关,以停止大多数循环(hacky,但有效):

for (i = 0; i < 10000; i++) {
  clearTimeout(i);
  clearInterval(i);
  cancelAnimationFrame(i);
}