我有一个页面,其中一些事件监听器附加到输入框和选择框。是否有一种方法可以找出哪些事件侦听器正在观察特定的DOM节点以及观察什么事件?
使用以下方法附加事件:
Prototype, Event.observe; 唐,addEventListener; 元素属性元素onclick
我有一个页面,其中一些事件监听器附加到输入框和选择框。是否有一种方法可以找出哪些事件侦听器正在观察特定的DOM节点以及观察什么事件?
使用以下方法附加事件:
Prototype, Event.observe; 唐,addEventListener; 元素属性元素onclick
当前回答
(重写这个问题的答案,因为它与这里有关。)
在调试时,如果你只想看到事件,我建议你选择…
视觉事件 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的内部结构,在未来的版本中可能会改变。不幸的是,我不知道其他方便的方法来访问这些事件。
其他回答
我最近在处理事件,想在一个页面中查看/控制所有事件。在研究了可能的解决方案后,我决定走自己的路,创建一个自定义系统来监视事件。所以,我做了三件事。
首先,我需要一个用于页面中所有事件监听器的容器:那就是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中实现这一点,还需要进一步修改。我以后可能会解决这个问题。
Opera 12(不是最新的基于Chrome Webkit的引擎)蜻蜓已经有一段时间了,并且很明显地显示在DOM结构中。在我看来,这是一个优秀的调试器,也是我仍然使用基于Opera 12的版本的唯一原因(没有v13, v14版本,基于v15 Webkit的版本仍然缺乏Dragonfly)
你可以通过把这个放在<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
粘贴到console中,可以在HTML元素旁边打印所有eventlistener
Array.from(document.querySelectorAll("*")).forEach(element => {
const events = getEventListeners(element)
if (Object.keys(events).length !== 0) {
console.log(element, events)
}
})
原型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];
}