Nav*_*eet 805 javascript events dom
我有一个页面,其中一些事件监听器附加到输入框和选择框.有没有办法找出哪些事件监听器正在观察特定的DOM节点以及哪些事件?
事件附件使用:
Event.observe
;addEventListener
;element.onclick
.And*_*ges 501
如果您只需要检查页面上发生的情况,可以尝试使用Visual Event书签.
更新:视觉事件2可用;
Cre*_*esh 356
这取决于事件的附加方式.为了说明,我们有以下点击处理程序:
var handler = function() { alert('clicked!') };
Run Code Online (Sandbox Code Playgroud)
我们将使用不同的方法将它附加到我们的元素,一些允许检查,一些不允许.
方法A)单个事件处理程序
element.onclick = handler;
// inspect
alert(element.onclick); // alerts "function() { alert('clicked!') }"
Run Code Online (Sandbox Code Playgroud)
方法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
Run Code Online (Sandbox Code Playgroud)
方法C):jQuery
$(element).click(handler);
Run Code Online (Sandbox Code Playgroud)
1.3.x的
// inspect
var clickEvents = $(element).data("events").click;
jQuery.each(clickEvents, function(key, value) {
alert(value) // alerts "function() { alert('clicked!') }"
})
Run Code Online (Sandbox Code Playgroud)1.4.x(将处理程序存储在对象中)
// inspect
var clickEvents = $(element).data("events").click;
jQuery.each(clickEvents, function(key, handlerObj) {
alert(handlerObj.handler) // alerts "function() { alert('clicked!') }"
// also available: handlerObj.type, handlerObj.namespace
})
Run Code Online (Sandbox Code Playgroud)方法D):原型(凌乱)
$(element).observe('click', handler);
Run Code Online (Sandbox Code Playgroud)
1.5.x的
// inspect
Event.observers.each(function(item) {
if(item[0] == element) {
alert(item[2]) // alerts "function() { alert('clicked!') }"
}
})
Run Code Online (Sandbox Code Playgroud)1.6到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){
alert(wrapper.handler) // alerts "function() { alert('clicked!') }"
})
Run Code Online (Sandbox Code Playgroud)1.6.1(好一点)
// inspect
var clickEvents = element.getStorage().get('prototype_event_registry').get('click');
clickEvents.each(function(wrapper){
alert(wrapper.handler) // alerts "function() { alert('clicked!') }"
})
Run Code Online (Sandbox Code Playgroud)Rag*_*hav 299
Chrome,Firefox,Vivaldi和Safari getEventListeners(domElement)
在其开发人员工具控制台中提供支持.
对于大多数调试目的,可以使用它.
以下是使用它的非常好的参考:https: //developers.google.com/chrome-developer-tools/docs/commandline-api#geteventlistenersobject
Ish*_*han 85
Chrome或Safari浏览器中的WebKit Inspector现在可以执行此操作.当您在"元素"窗格中选择DOM元素时,它将显示DOM元素的事件侦听器.
Iva*_*nos 70
可以在JavaScript中列出所有事件监听器:这并不难; 你只需要破解prototype
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});
};
Run Code Online (Sandbox Code Playgroud)
现在每个anchor元素(a
)都有一个lastListenerInfo
包含所有侦听器的属性.它甚至可以用于删除具有匿名功能的侦听器.
Pra*_*oni 51
在Google Chrome中使用getEventListeners :
getEventListeners(document.getElementByID('btnlogin'));
getEventListeners($('#btnlogin'));
Run Code Online (Sandbox Code Playgroud)
Luk*_*uke 41
(重写这个问题的答案,因为它在这里是相关的.)
调试时,如果你只是想看事件,我建议......
如果要在代码中使用事件,并且在1.8版之前使用jQuery ,则可以使用:
$(selector).data("events")
Run Code Online (Sandbox Code Playgroud)
得到事件.从版本1.8开始,使用.data("events")已停止使用(请参阅此错误凭单).您可以使用:
$._data(element, "events")
Run Code Online (Sandbox Code Playgroud)
另一个例子:将特定链接上的所有点击事件写入控制台:
var $myLink = $('a.myClass');
console.log($._data($myLink[0], "events").click);
Run Code Online (Sandbox Code Playgroud)
(有关工作示例,请参见http://jsfiddle.net/HmsQC/)
不幸的是,使用$ ._ data不建议除了调试之外,因为它是一个内部jQuery结构,并且可能在将来的版本中发生变化.不幸的是,我知道没有其他简单的方法可以访问这些事件.
Jan*_*roň 26
1:Prototype.observe
使用Element.addEventListener(参见源代码)
2:您可以覆盖Element.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);
};
})();
Run Code Online (Sandbox Code Playgroud)
阅读所有活动:
var clicks = someElement.eventListenerList.click;
if(clicks) clicks.forEach(function(f) {
alert("I listen to this function: "+f.toString());
});
Run Code Online (Sandbox Code Playgroud)
并且不要忘记覆盖Element.removeEventListener
以从自定义中删除事件Element.eventListenerList
.
3:Element.onclick
酒店需要特别照顾:
if(someElement.onclick)
alert("I also listen tho this: "+someElement.onclick.toString());
Run Code Online (Sandbox Code Playgroud)
4:不要忘记Element.onclick
内容属性:这是两个不同的东西:
someElement.onclick = someHandler; // IDL attribute
someElement.setAttribute("onclick","otherHandler(event)"); // content attribute
Run Code Online (Sandbox Code Playgroud)
所以你也需要处理它:
var click = someElement.getAttribute("onclick");
if(click) alert("I even listen to this: "+click);
Run Code Online (Sandbox Code Playgroud)
Visual Event bookmarklet(在最流行的答案中提到)只窃取自定义库处理程序缓存:
事实证明,W3C推荐的DOM接口没有提供标准方法来找出哪些事件监听器附加到特定元素.虽然这似乎是一种疏忽,但有人建议将一个名为eventListenerList的属性包含在3级DOM规范中,但遗憾的是在后续草稿中删除了该属性.因此,我们不得不查看各个Javascript库,这些库通常维护附加事件的缓存(以便以后可以删除它们并执行其他有用的抽象).
因此,为了使Visual Event显示事件,它必须能够从Javascript库中解析事件信息.
元素重写可能有问题(即因为有一些DOM特定的功能,如实时集合,无法在JS中编码),但它本身提供了eventListenerList支持,它可以在Chrome,Firefox和Opera中运行(在IE7中不起作用) ).
Jon*_*n z 22
您可以将本地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>
Run Code Online (Sandbox Code Playgroud)
H/T @ les2
alj*_*gom 14
2022 年更新:
在 中Chrome Developer Tools
,Elements panel
有一个Event Listeners
选项卡,您可以在其中查看该元素的侦听器。
您还可以取消选择“祖先”,以便它仅显示该元素的侦听器
Gab*_*son 13
获取页面上的所有 eventListeners 与其元素一起打印
Array.from(document.querySelectorAll("*")).forEach(e => {
const ev = getEventListeners(e)
if (Object.keys(ev).length !== 0) console.log(e, ev)
})
Run Code Online (Sandbox Code Playgroud)
Mic*_*ler 12
如果你有Firebug,你可以用来console.dir(object or array)
在任何JavaScript标量,数组或对象的控制台日志中打印一个漂亮的树.
尝试:
console.dir(clickEvents);
Run Code Online (Sandbox Code Playgroud)
要么
console.dir(window);
Run Code Online (Sandbox Code Playgroud)
完全工作的解决方案基于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];
};
})();
Run Code Online (Sandbox Code Playgroud)
用法:
someElement.getEventListeners([name])
- 返回事件侦听器列表,如果设置了name,则返回该事件的侦听器数组
someElement.clearEventListeners([name])
- 删除所有事件侦听器,如果设置了name,则仅删除该事件的侦听器
小智 5
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];
}
Run Code Online (Sandbox Code Playgroud)
我试图在 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);
}
Run Code Online (Sandbox Code Playgroud)
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<body>
</body>
Run Code Online (Sandbox Code Playgroud)
我最近正在处理事件,想要查看/控制页面中的所有事件。在研究了可能的解决方案后,我决定按照自己的方式创建一个自定义系统来监视事件。所以,我做了三件事。
首先,我需要一个用于页面中所有事件侦听器的容器:这就是对象EventListeners
。它具有三个有用的方法:add()
、remove()
和get()
。
接下来,我创建了一个EventListener
对象来保存事件的必要信息,即:target
、type
、callback
、options
、useCapture
、wantsUntrusted
,并添加了一个remove()
删除侦听器的方法。
最后,我扩展了本机addEventListener()
和removeEventListener()
方法,使它们可以与我创建的对象(EventListener
和EventListeners
)一起使用。
用法:
var bodyClickEvent = document.body.addEventListener("click", function () {
console.log("body click");
});
// bodyClickEvent.remove();
Run Code Online (Sandbox Code Playgroud)
addEventListener()
创建一个EventListener
对象,将其添加到EventListeners
并返回该EventListener
对象,以便稍后可以将其删除。
EventListeners.get()
可用于查看页面中的监听器。它接受一个EventTarget
或一个字符串(事件类型)。
// EventListeners.get(document.body);
// EventListeners.get("click");
Run Code Online (Sandbox Code Playgroud)
演示
假设我们想了解当前页面中的每个事件侦听器。我们可以做到这一点(假设您使用脚本管理器扩展,在本例中为 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);
Run Code Online (Sandbox Code Playgroud)
当我们列出所有侦听器时,它显示有 299 个事件侦听器。“似乎”有一些重复项,但我不知道它们是否真的重复。并非每个事件类型都是重复的,因此所有这些“重复项”可能是单个侦听器。
代码可以在我的存储库中找到。我本来不想把它贴在这里,因为它太长了。
更新:这似乎不适用于 jQuery。当我检查 EventListener 时,我看到回调是
function(b){return"undefined"!=typeof r&&r.event.triggered!==b.type?r.event.dispatch.apply(a,arguments):void 0}
Run Code Online (Sandbox Code Playgroud)
我相信这属于 jQuery,而不是实际的回调。jQuery 将实际回调存储在 EventTarget 的属性中:
$(document.body).click(function () {
console.log("jquery click");
});
Run Code Online (Sandbox Code Playgroud)
要删除事件侦听器,需要将实际回调传递给该removeEventListener()
方法。因此,为了使其能够与 jQuery 一起工作,需要进一步修改。我将来可能会解决这个问题。
归档时间: |
|
查看次数: |
494365 次 |
最近记录: |