我有一个页面,其中一些事件监听器附加到输入框和选择框。是否有一种方法可以找出哪些事件侦听器正在观察特定的DOM节点以及观察什么事件?

使用以下方法附加事件:

Prototype, Event.observe; 唐,addEventListener; 元素属性元素onclick


当前回答

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中不工作)。

其他回答

使用getEventListeners在谷歌Chrome:

getEventListeners(document.getElementByID('btnlogin'));
getEventListeners($('#btnlogin'));

这取决于事件是如何附加的。为了说明,假设我们有以下点击处理程序:

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文件中函数声明的行。

更改这些函数将允许您记录添加的侦听器:

EventTarget.prototype.addEventListener
EventTarget.prototype.attachEvent
EventTarget.prototype.removeEventListener
EventTarget.prototype.detachEvent

朗读其余的听众

console.log(someElement.onclick);
console.log(someElement.getAttribute("onclick"));

如果你有Firebug,你可以使用控制台。在任何JavaScript标量、数组或对象的控制台日志中打印一个漂亮的树。

试一试:

console.dir(clickEvents);

or

console.dir(window);

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中不工作)。