如何查看附加到HTML元素的事件?

66

我是一名新程序员,还在学习中。

这是我正在努力理解的代码:

<div id="buy" class="buy button">Buy</div>

当我点击div(按钮)时,会执行一些JavaScript代码,但我不知道它在哪里。如何确定单击发生时触发了哪个函数?某种方式上,监听器已附加到此元素。


你是在问如何将事件处理程序附加到div吗? - Blazemonger
2
附注:您不应将div用作按钮,而应改用<button type="button">我是按钮</button>或<a href="www.google.com">我是链接</a>。 - Mauno Vähä
1
@RandyMarsh 我不知道事件监听器在哪里,这就是我想要找出的。因为通常我在学校里学到的是你可以在元素中添加一个onclick属性,然后指定需要触发的函数。但是使用Firebug时,当我将鼠标悬停在该元素上时,我看不到事件 :( 他们是如何做到的? - Vaso A.
监听器不一定直接附加在该元素上,它可以在祖先元素上。 - user1106925
我们有FireFox和Chrome的解决方案。我想知道IE怎么样...不抱太大希望。 - Chad Harrison
Chrome的事件监听器非常棒!! - rhapsodyn
11个回答

106
在Google Chrome的开发者工具中(点击扳手图标>工具>开发者工具),选择元素选项卡中的元素,在右侧打开“事件侦听器”面板,您将看到所有事件。

4
喜欢使用快捷键的人,按下 F12 也可以打开这个。 - Erty Seidohl
@yoelp <div class="comm"> <a href="#">A</a> </div>。当我检查锚点的“事件监听器”时,它显示Click-> a (jquery.min.js)。相应的单击事件处理程序函数在“navigation.js”中,为什么它显示jquery.min.js而不是navigation.js?您要我为此提出单独的问题吗? - SyAu
@SyAu 因为事件是由 jQuery 绑定而不是 navigation.js,navigation.js 只是调用了 jQuery 的绑定函数,但实际的绑定是在 jQuery 中发生的。 - yoelp

24

如果你使用Firefox和Firebug,你可以尝试安装FireQuery插件。它可以让你看到由jQuery绑定的处理程序。http://firequery.binaryage.com/


11
你如何知道它是使用jQuery附加的? - user1106925
FireQuery 似乎是我一直在寻找的工具,有了它,我可以随时知道任何元素绑定的事件,例如 onchange、onmouseover 等等。 - Vaso A.
4
对于使用纯JavaScript绑定的DOM Level 1+2侦听器绑定的事件,这种方法将不起作用。 - jAndy
2
@kissmyface:他说的是“如果你用Firefox”,这与我的评论无关。 - user1106925
1
jQuery事件处理程序也位于jQuery的数据缓存中,因此可以使用$().data('events')在任何有效的选择器上访问它们。 - John Strickler

13

你不能仅用 ECMAscript 来实现一个真正好的方法。例如,如果通过DOM Level 1添加了一个点击事件处理程序,形式为:

document.getElementById('buy').onclick = function() {};

当然,你可以轻松地拦截节点本身的属性。如果涉及到DOM Level 2.addEventListener().attachEvent(),情况会变得更加复杂。此时,你将没有“位置”可以查找所有不同的监听函数是从哪里绑定的。

使用jQuery可以让事情变得更简单。jQuery将所有事件处理程序函数保存在一个特殊对象中,该对象与调用的DOM节点链接在一起。你可以通过获取节点的 .data() 扩展属性来检查它。

$('#buy').data('events');

然而,现在我已经描述了三种不同的将事件监听器绑定到节点的方法(实际上只有两种,因为像jQuery这样的库当然也使用DOM Level 1或2方法)。

如果一个事件是通过委托触发的,那么情况就真的很糟糕了。这意味着,我们将单击事件绑定在某个父节点上,等待该事件冒泡到我们这里,以便我们可以检查 target。所以现在,nodeevent listener之间甚至没有直接关系。

总结一下,要注意浏览器插件或类似VisualEvent的东西。


非常全面的回答。唯一的问题是,如果事件绑定到祖先元素上,那么.data('events')解决方案将无法起作用。 - user1106925

9

所有DOM level 0事件以及来自广泛使用的框架(jQuery,Prototype,Mootools,YUI等)已知版本的所有事件实际上都可以显示。但它无法显示通过纯JavaScript附加的DOM level 2事件观察器。 - Victor

5

2
你怎么知道它是用jQuery绑定的,而且直接绑定到元素上的? - user1106925
控制台显示为“未定义”。 - derloopkat

4
使用传统的element.onclick=或HTML<element onclick="handler">添加的事件处理程序可以轻松地从脚本或调试器中检索到element.onclick属性。使用DOM Level 2 Events addEventListener方法和IE的attachEvent添加的事件处理程序目前无法从脚本中检索。DOM Level 3曾经提出element.eventListenerList来获取所有监听器,但不清楚它是否会成为最终规范。今天没有任何浏览器实现此功能。

3

3
你如何知道它是使用jQuery附加的? - user1106925

2

你是否正在使用jQuery?如果是,你需要搜索以下三行代码之一:

$("#buy").click //the div is refered by its id

或者

$(".buy").click //the div is refered to by the style "buy"

或者
$(".button").click //refered to by the style "button"

大多数新型浏览器都内置了“开发者工具”,只需按下F12(至少在IE和Chrome中如此),即可帮助您进行进一步的调试和跟踪。


谢谢,我可以在警报时看到函数的主体,但我无法看到它的位置以便进行编辑。 - Vaso A.
5
除了这些方法之外,还有许多其他绑定元素的方式。即使使用了 click,选择器也可能会完全不同。 - user1106925

2
以下是我过去使用过的内容,我认为可能是您正在寻找的内容。它所做的是监视页面元素上的属性(在下面的示例中,它是文档的“Title”属性),然后在该属性更改时显示带有JS调用堆栈的警报。您需要在尝试查找触发代码之前将其放入DOM中,但希望您能够识别出问题的原因。
我建议使用Firefox并获取JavaScript调试的Firebug插件。
// Call stack code
function showCallStack() {
   var f=showCallStack,result="Call stack:\n";

   while((f=f.caller)!==null) {
      var sFunctionName = f.toString().match(/^function (\w+)\(/)
      sFunctionName = (sFunctionName) ? sFunctionName[1] : 'anonymous function';
      result += sFunctionName;
      result += getArguments(f.toString(), f.arguments);
      result += "\n";
   }
   alert(result);
}


function getArguments(sFunction, a) {
   var i = sFunction.indexOf(' ');
   var ii = sFunction.indexOf('(');
   var iii = sFunction.indexOf(')');
   var aArgs = sFunction.substr(ii+1, iii-ii-1).split(',')
   var sArgs = ''; 
   for(var i=0; i<a.length; i++) {
      var q = ('string' == typeof a[i]) ? '"' : '';
      sArgs+=((i>0) ? ', ' : '')+(typeof a[i])+' '+aArgs[i]+':'+q+a[i]+q+'';
   }
   return '('+sArgs+')';
} 

var watchTitle = function(id, oldval, newval) { showCallStack(); }

// !! This is all you should need to update, setting it to whatever you want to watch.
document.watch("title", watchTitle);  

“watch” 方法可能只被 Firefox(Gecko 浏览器)支持? - MrWhite

2
这是我发现的最简单的方法: http://www.sprymedia.co.uk/article/Visual+Event 在JavaScript中处理事件时,很容易忘记哪个事件在哪里订阅。如果您使用大量事件,这一点尤其明显,这在采用渐进增强的现代界面中是典型的。从技术角度来看,JavaScript库也增加了另一个监听器的复杂性,而从开发人员的角度来看,它们当然可以使生活更轻松!但是,当事情出错时,很难追踪为什么会出错。
因此,我编写了一个名为Visual Event的JavaScript书签工具,它在页面上直观地显示订阅事件的元素,这些事件是什么以及触发时运行事件的函数是什么。这主要是为了帮助调试,但是在其他页面上查看订阅的事件也非常有趣和有益。
在那里有一个书签按钮,您可以将其拖到您的工具栏(FF或Chrome)中,然后只需单击按钮即可在想要查看附加事件的任何页面上使用!(至少适用于由jQuery或其他库附加的事件)。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接