我有一个页面,其中一些事件监听器附加到输入框和选择框。是否有一种方法可以找出哪些事件侦听器正在观察特定的DOM节点以及观察什么事件?
使用以下方法附加事件:
Prototype, Event.observe; 唐,addEventListener; 元素属性元素onclick
我有一个页面,其中一些事件监听器附加到输入框和选择框。是否有一种方法可以找出哪些事件侦听器正在观察特定的DOM节点以及观察什么事件?
使用以下方法附加事件:
Prototype, Event.observe; 唐,addEventListener; 元素属性元素onclick
当前回答
更改这些函数将允许您记录添加的侦听器:
EventTarget.prototype.addEventListener
EventTarget.prototype.attachEvent
EventTarget.prototype.removeEventListener
EventTarget.prototype.detachEvent
朗读其余的听众
console.log(someElement.onclick);
console.log(someElement.getAttribute("onclick"));
其他回答
粘贴到console中,可以在HTML元素旁边打印所有eventlistener
Array.from(document.querySelectorAll("*")).forEach(element => {
const events = getEventListeners(element)
if (Object.keys(events).length !== 0) {
console.log(element, events)
}
})
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中不工作)。
Chrome, Firefox, Vivaldi和Safari在他们的开发人员工具控制台中支持getEventListeners(domElement)。
对于大多数调试目的,都可以使用这种方法。
下面是一个很好的使用它的参考: getEventListeners函数
Clifford Fajardo在评论中给出了高度投票的建议:
getEventListeners($0)将获得你在Chrome开发工具中关注的元素的事件监听器。
这取决于事件是如何附加的。为了说明,假设我们有以下点击处理程序:
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文件中函数声明的行。
我最近在处理事件,想在一个页面中查看/控制所有事件。在研究了可能的解决方案后,我决定走自己的路,创建一个自定义系统来监视事件。所以,我做了三件事。
首先,我需要一个用于页面中所有事件监听器的容器:那就是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中实现这一点,还需要进一步修改。我以后可能会解决这个问题。