Как найти прослушиватели событий на узле DOM при отладке или из кода JavaScript? - PullRequest
762 голосов
/ 15 января 2009

У меня есть страница, на которой некоторые слушатели событий прикреплены к полям ввода и полям выбора. Есть ли способ узнать, какие слушатели событий наблюдают за конкретным узлом DOM и для какого события?

События прикрепляются с использованием:

  1. Прототип Event.observe;
  2. DOM's addEventListener;
  3. как атрибут элемента element.onclick.

Ответы [ 18 ]

12 голосов
/ 08 января 2010

Если у вас есть Firebug , вы можете использовать console.dir(object or array), чтобы напечатать красивое дерево в журнале консоли любого скаляра JavaScript, массива или объекта.

Попробуйте:

console.dir(clickEvents);

или

console.dir(window);
8 голосов
/ 27 июня 2015

Полностью рабочее решение на основе ответа Яна Турона - ведет себя как 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]) - вернуть список слушателей события, если установлено имя, вернуть массив слушателей для этого события

someElement.clearEventListeners([name]) - удалить все прослушиватели событий, если задано имя, удалить только прослушиватели этого события

8 голосов
/ 28 ноября 2013

Opera 12 (не последняя версия на основе движка Chrome Webkit) Dragonfly имеет это некоторое время и, очевидно, отображается в структуре DOM. На мой взгляд, это превосходный отладчик, и это единственная причина, почему я до сих пор использую версию для Opera 12 (версии v13, v14 нет, а в версии 15 для Webkit отсутствует Dragonfly)

enter image description here

4 голосов
/ 17 января 2013

Прототип 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];
}
3 голосов
/ 28 февраля 2017

Существует хорошее расширение jQuery Events :

enter image description here (тема источник )

2 голосов
/ 19 мая 2015

Я пытаюсь сделать это в 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);
	}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<body>
</body>
0 голосов
/ 18 апреля 2019

изменение этих функций позволит вам регистрировать добавленных слушателей:

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

читать остальных слушателей с

console.log(someElement.onclick);
console.log(someElement.getAttribute("onclick"));
0 голосов
/ 28 июня 2018

Я недавно работал с событиями и хотел просмотреть / контролировать все события на странице. Посмотрев на возможные решения, я решил пойти своим путем и создать собственную систему мониторинга событий. Итак, я сделал три вещи.

Во-первых, мне нужен контейнер для всех прослушивателей событий на странице: это объект 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();

addEventListener() создает объект EventListener, добавляет его к EventListeners и возвращает объект EventListener, чтобы его можно было удалить позже.

EventListeners.get() можно использовать для просмотра слушателей на странице. Он принимает EventTarget или строку (тип события).

// EventListeners.get(document.body);
// EventListeners.get("click");

Демо

Допустим, мы хотим знать всех слушателей событий на этой текущей странице. Мы можем сделать это (при условии, что вы используете расширение диспетчера сценариев, в данном случае 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 слушателей событий. «Кажется» есть некоторые дубликаты, но я не знаю, действительно ли они дубликаты. Не каждый тип события дублируется, поэтому все эти «дубликаты» могут быть отдельными слушателями.

screenshot of console listing all event listeners in this page

Код можно найти в моем хранилище. Я не хотел публиковать его здесь, потому что он довольно длинный.


Обновление: Это не похоже на работу с 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");
});

enter image description here

Чтобы удалить прослушиватель событий, фактический обратный вызов должен быть передан методу removeEventListener(). Так что для того, чтобы заставить это работать с jQuery, он нуждается в дальнейшей модификации. Я мог бы исправить это в будущем.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...