Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/426.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何在调试时或从JavaScript代码中查找DOM节点上的事件侦听器?_Javascript_Events_Dom - Fatal编程技术网

如何在调试时或从JavaScript代码中查找DOM节点上的事件侦听器?

如何在调试时或从JavaScript代码中查找DOM节点上的事件侦听器?,javascript,events,dom,Javascript,Events,Dom,我有一个页面,其中一些事件侦听器连接到输入框和选择框。有没有办法找出哪些事件侦听器正在观察某个特定的DOM节点以及观察哪个事件 事件通过以下方式附加: 事件。观察 DOM的addEventListener 作为元素属性element.onclick 这取决于事件的附加方式。为便于说明,假设我们有以下单击处理程序: var handler = function() { alert('clicked!') }; 我们将使用不同的方法将其附加到元素上,有些方法允许检查,有些方法不允许 方法A)单个事

我有一个页面,其中一些事件侦听器连接到输入框和选择框。有没有办法找出哪些事件侦听器正在观察某个特定的DOM节点以及观察哪个事件

事件通过以下方式附加:

  • 事件。观察
  • DOM的
    addEventListener
  • 作为元素属性
    element.onclick

  • 这取决于事件的附加方式。为便于说明,假设我们有以下单击处理程序:

    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

    • 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(将处理程序存储在对象中)

    • 1.7+(非常好)

      使用来自的知识制作

    (见和)

    方法D):原型(凌乱)

    • 1.5.x

       // inspect
       Event.observers.each(function(item) {
           if(item[0] == element) {
               console.log(item[2]) // "function() { alert('clicked!') }"
           }
       })
      
    • 1.6至1.6.0.3,包括在内(此处难度很大)

    在控制台中单击结果输出(显示函数文本)时,控制台将直接导航到相关JS文件中函数声明的行。

    如果有,可以使用
    console.dir(对象或数组)
    在控制台日志中打印任意JavaScript标量、数组、,或对象

    尝试:


    如果您只需要检查页面上发生的事情,您可以尝试使用bookmarklet


    更新:可用。

    Chrome或Safari浏览器中的WebKit Inspector现在可以执行此操作。当您在“元素”窗格中选择DOM元素时,它将显示该元素的事件侦听器。

    可以用JavaScript列出所有事件侦听器:这并不难;您只需破解
    原型
    的HTML元素方法(在添加侦听器之前)

    现在,每个锚元素(
    a
    )都将有一个包含其所有侦听器的
    lastListenerInfo
    属性。它甚至可以用于删除具有匿名函数的侦听器。

    (由于答案与此处相关,因此将从中重写。)

    在调试时,如果您只想查看事件,我建议您选择

  • Chrome开发者工具的元素部分:选择一个元素并在右下角寻找“事件监听器”(类似于Firefox)
  • 如果要在代码中使用事件,并且使用的是1.8版之前的jQuery,则可以使用:

    $(selector).data("events")
    
    来获取事件从1.8版开始,不再使用.data(“事件”)(请参阅)。您可以使用:

    $._data(element, "events")
    
    另一个示例:将某个链接上的所有单击事件写入控制台:

    var $myLink = $('a.myClass');
    console.log($._data($myLink[0], "events").click);
    
    (有关工作示例,请参见)

    不幸的是,使用$。\u数据除了调试之外,不建议使用它,因为它是一个内部jQuery结构,并且在将来的版本中可能会更改。不幸的是,我知道没有其他简单的方法可以访问事件。

    Prototype 1.7.1 way

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

    Chrome、Firefox、Vivaldi和Safari支持开发者工具控制台中的getEventListeners(DoElement)

    对于大多数调试目的,都可以使用这种方法

    下面是使用它的一个很好的参考:

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


    谷歌浏览器中使用getEventListeners

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

    1:
    Prototype.observe
    使用Element.addEventListener(请参阅)

    2:您可以重写
    元素。addEventListener
    以记住添加的侦听器(handy属性
    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());
    });
    
    不要忘记覆盖
    元素.removeEventListener
    以从自定义
    元素.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(在最流行的答案中提到)仅窃取自定义库处理程序缓存:

    事实证明,W3C没有提供标准方法 建议使用DOM接口来了解事件侦听器是什么 附加到特定元素的。虽然这似乎是一个问题 在监督方面,有人提议将一处名为 eventListenerList符合3级DOM规范,但 不幸的是,在以后的草稿中删除了。因此,我们被迫这样做 查看各个Javascript库,它们通常 维护附加事件的缓存(以便以后可以删除和删除它们) 执行其他有用的抽象)

    因此,为了让可视事件显示事件,它必须能够 从Javascript库中解析事件信息


    元素重写可能有问题(例如,因为有一些特定于DOM的功能,如live collections,无法在JS中编码),但它提供了eventListenerList本机支持,并且可以在Chrome、Firefox和Opera中工作(在IE7中不起作用)。

    Firefox开发工具现在可以做到这一点。通过单击每个元素显示屏右侧的“ev”按钮显示事件,包括和事件


    我试图在jQuery 2.1中使用“
    $().click()->$(element).data(“events”).click;
    ”方法来实现这一点,但它不起作用

    我意识到在我的例子中,只有$.\u data()函数起作用:

    $(doc)
    
    $._data(element, "events")
    
    var $myLink = $('a.myClass');
    console.log($._data($myLink[0], "events").click);
    
    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];
    }
    
    getEventListeners(document.getElementByID('btnlogin'));
    getEventListeners($('#btnlogin'));
    
    (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());
    });
    
    if(someElement.onclick)
      alert("I also listen tho this: "+someElement.onclick.toString());
    
    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);
    
    (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];
      };
    })();
    
    <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>
    
    var bodyClickEvent = document.body.addEventListener("click", function () {
        console.log("body click");
    });
    
    // bodyClickEvent.remove();
    
    // EventListeners.get(document.body);
    // EventListeners.get("click");
    
    // ==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);
    
    function(b){return"undefined"!=typeof r&&r.event.triggered!==b.type?r.event.dispatch.apply(a,arguments):void 0}
    
    $(document.body).click(function () {
        console.log("jquery click");
    });
    
    EventTarget.prototype.addEventListener
    EventTarget.prototype.attachEvent
    EventTarget.prototype.removeEventListener
    EventTarget.prototype.detachEvent
    
    console.log(someElement.onclick);
    console.log(someElement.getAttribute("onclick"));
    
    Array.from(document.querySelectorAll("*")).forEach(e => {
        const ev = getEventListeners(e)
        if (Object.keys(ev).length !== 0) console.log(e, ev)
    })