我有一个页面,其中一些事件监听器附加到输入框和选择框。是否有一种方法可以找出哪些事件侦听器正在观察特定的DOM节点以及观察什么事件?
使用以下方法附加事件:
Prototype, Event.observe; 唐,addEventListener; 元素属性元素onclick
我有一个页面,其中一些事件监听器附加到输入框和选择框。是否有一种方法可以找出哪些事件侦听器正在观察特定的DOM节点以及观察什么事件?
使用以下方法附加事件:
Prototype, Event.observe; 唐,addEventListener; 元素属性元素onclick
当前回答
我最近在处理事件,想在一个页面中查看/控制所有事件。在研究了可能的解决方案后,我决定走自己的路,创建一个自定义系统来监视事件。所以,我做了三件事。
首先,我需要一个用于页面中所有事件监听器的容器:那就是eventlisteners对象。它有三个有用的方法:add()、remove()和get()。
接下来,我创建了一个EventListener对象来保存事件的必要信息,即:目标、类型、回调、选项、useCapture、wantsUntrusted,并添加了一个方法remove()来删除侦听器。
最后,我扩展了本机addEventListener()和removeEventListener()方法,使它们与我创建的对象(EventListener和EventListeners)一起工作。
用法:
var bodyClickEvent = document.body.addEventListener("click", function () {
console.log("body click");
});
// bodyClickEvent.remove();
addEventListener()创建一个EventListener对象,将其添加到EventListener并返回EventListener对象,以便稍后将其删除。
EventListeners.get()可用于查看页面中的侦听器。它接受一个EventTarget或一个字符串(事件类型)。
// EventListeners.get(document.body);
// EventListeners.get("click");
Demo
假设我们想知道当前页面中的每个事件侦听器。我们可以这样做(假设您正在使用脚本管理器扩展,在本例中是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/EventListener.js")
.then(function (response) {
return response.text();
})
.then(function (text) {
eval(text);
window.EventListeners = EventListeners;
});
})(window);
当我们列出所有监听器时,它说有299个事件监听器。“好像”有一些复制品,但我不知道是不是真的复制品。并不是每个事件类型都是重复的,所以所有这些“重复”可能是一个单独的侦听器。
代码可以在我的存储库中找到。我不想把它贴在这里,因为它太长了。
更新:这似乎不能与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");
});
要删除事件监听器,实际的回调需要传递给removeEventListener()方法。因此,为了在jQuery中实现这一点,还需要进一步修改。我以后可能会解决这个问题。
其他回答
Firefox开发工具现在可以做到这一点。事件是通过点击每个元素右侧的“ev”按钮来显示的,包括jQuery和DOM事件。
(重写这个问题的答案,因为它与这里有关。)
在调试时,如果你只想看到事件,我建议你选择…
视觉事件 Chrome开发者工具的元素部分:选择一个元素,在右下角寻找“事件监听器”(类似于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:原型。observe使用Element。addEventListener(参见源代码)
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);
};
})();
通过以下方式阅读所有活动:
var clicks = someElement.eventListenerList.click;
if(clicks) clicks.forEach(function(f) {
alert("I listen to this function: "+f.toString());
});
不要忘记重写Element。removeEventListener从自定义的Element.eventListenerList中删除事件。
3:元素。Onclick属性在这里需要特别注意:
if(someElement.onclick)
alert("I also listen tho this: "+someElement.onclick.toString());
4:不要忘记元素。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 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). As such, in order for Visual Event to show events, it must be able to parse the event information out of a Javascript library.
元素覆盖可能是有问题的(即,因为有一些DOM特定的特性,如活动集合,不能在JS中编码),但它提供了eventListenerList原生支持,它在Chrome, Firefox和Opera中工作(在IE7中不工作)。
在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});
};
现在每个锚元素(a)都有一个lastListenerInfo属性,其中包含它所有的侦听器。它甚至可以用匿名函数删除侦听器。
我最近在处理事件,想在一个页面中查看/控制所有事件。在研究了可能的解决方案后,我决定走自己的路,创建一个自定义系统来监视事件。所以,我做了三件事。
首先,我需要一个用于页面中所有事件监听器的容器:那就是eventlisteners对象。它有三个有用的方法:add()、remove()和get()。
接下来,我创建了一个EventListener对象来保存事件的必要信息,即:目标、类型、回调、选项、useCapture、wantsUntrusted,并添加了一个方法remove()来删除侦听器。
最后,我扩展了本机addEventListener()和removeEventListener()方法,使它们与我创建的对象(EventListener和EventListeners)一起工作。
用法:
var bodyClickEvent = document.body.addEventListener("click", function () {
console.log("body click");
});
// bodyClickEvent.remove();
addEventListener()创建一个EventListener对象,将其添加到EventListener并返回EventListener对象,以便稍后将其删除。
EventListeners.get()可用于查看页面中的侦听器。它接受一个EventTarget或一个字符串(事件类型)。
// EventListeners.get(document.body);
// EventListeners.get("click");
Demo
假设我们想知道当前页面中的每个事件侦听器。我们可以这样做(假设您正在使用脚本管理器扩展,在本例中是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/EventListener.js")
.then(function (response) {
return response.text();
})
.then(function (text) {
eval(text);
window.EventListeners = EventListeners;
});
})(window);
当我们列出所有监听器时,它说有299个事件监听器。“好像”有一些复制品,但我不知道是不是真的复制品。并不是每个事件类型都是重复的,所以所有这些“重复”可能是一个单独的侦听器。
代码可以在我的存储库中找到。我不想把它贴在这里,因为它太长了。
更新:这似乎不能与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");
});
要删除事件监听器,实际的回调需要传递给removeEventListener()方法。因此,为了在jQuery中实现这一点,还需要进一步修改。我以后可能会解决这个问题。