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

使用以下方法附加事件:

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


当前回答

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

试一试:

console.dir(clickEvents);

or

console.dir(window);

其他回答

完全工作的解决方案基于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];
  };
})();

用法:

someElement.getEventListeners([name]) -返回事件监听器列表,如果设置了name则返回该事件的监听器数组

someElement.clearEventListeners([name]) -删除所有事件监听器,如果设置了name,则只删除该事件的监听器

Opera 12(不是最新的基于Chrome Webkit的引擎)蜻蜓已经有一段时间了,并且很明显地显示在DOM结构中。在我看来,这是一个优秀的调试器,也是我仍然使用基于Opera 12的版本的唯一原因(没有v13, v14版本,基于v15 Webkit的版本仍然缺乏Dragonfly)

原型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];
}

2022年更新:

在Chrome开发工具的元素面板中,有一个事件监听器选项卡,在那里你可以看到元素的监听器。

你也可以取消选择“祖宗”,这样它只显示该元素的监听器

你可以通过把这个放在<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