Как найти слушателей событий на узле DOM в JavaScript или при отладке?

avatar
Navneet
15 января 2009 в 14:19
654442
19
932

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

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

  1. Прототип Event.observe;
  2. DOM addEventListener;
  3. Как атрибут элемента element.onclick.
Источник
Crescent Fresh
15 января 2009 в 15:07
3

Как связаны события в первую очередь? Вы используете библиотеку (например, Prototype, jQuery и т. Д.)?

Braden Best
10 мая 2017 в 23:13
0

Важно отметить, что несколько функций обратного вызова могут быть присоединены для одного и того же типа события через element.addEventListener(type, callback, [bubble]), в то время как element.onclick = function будет перезаписываться каждый раз, когда вы назначаете.

Gabriel Petersson
22 июля 2020 в 14:23
1

Получает все события вместе с их соответствующим элементом: Array.from(document.querySelectorAll("*")).forEach(e => { const ev = getEventListeners(e); if (Object.keys(ev).length !== 0) {console.log(e, ev)} })

John Henckel
22 октября 2020 в 15:00
0

Вы можете захватить addEventListener и захватить список всех слушателей в элементе DOM. Вот пример кода coderhelper.com/a/64484951/1812732

Ответы (19)

avatar
Andrew Hedges
6 августа 2010 в 17:48
517

Если вам просто нужно проверить, что происходит на странице, вы можете попробовать букмарклет Визуальное событие.

Обновление : Визуальное событие 2 доступно.

Robin Maben
15 сентября 2011 в 08:47
2

Идеальный! Превосходит плагин Firebug EventBug.

Tony R
8 марта 2012 в 21:57
29

Это добавляет на страницу миллиард элементов, многие из которых являются изображениями. Его полезность значительно снижается на странице с множеством обработчиков событий (у меня 17k, а загрузка Visual Event заняла около 3 минут).

kmote
17 февраля 2013 в 19:57
15

Я считаю, что упомянутое расширение Chrome @ssharma - это , доступное здесь

hiway
19 ноября 2013 в 03:50
1

Визиальное событие не работает, если страница ссылается на стороннюю библиотеку js. Вызывает ошибку: XMLHttpRequest не может загрузить A.com/js/jquery-ui-1.10.3.custom.js?_=1384831682813. Источник B.com не разрешен Access-Control-Allow-Origin.

ken
11 декабря 2013 в 20:45
0

Это очевидно из источника, но букмарклет внедряет на ваш сайт сторонний скрипт. Это может быть хорошо для большинства случаев, но если вы имеете дело с данными PCI, HIPAA и т. Д., Вам, вероятно, следует держаться подальше.

oriadam
31 декабря 2015 в 05:27
8

Внутренние инструменты разработчика Chrome и FF (F12) имеют встроенную программу просмотра событий! Chrome: на вкладке «Элементы» выберите элемент и посмотрите, что справа: Стиль, Вычисленное, Слушатели событий

doABarrelRoll721
20 февраля 2016 в 02:11
1

Кажется, что Visual Event не поддерживает способ добавления EventListeners в DOM 2. Для меня это крайне странно и непонятно, поскольку поддерживает полдюжины неосновных библиотек.

Michael
20 мая 2016 в 21:40
0

@oriadam Замечательно! Есть ли способ определить, какой из них я хочу посмотреть быстрее, чем открывать их по очереди?

oriadam
21 мая 2016 в 22:17
0

В @Michael Firefox есть этот маленький значок «ev» рядом с элементами, у которых есть прослушиватели событий. Мне не удалось найти похожий значок в Chrome, извините. doABarrelRoll721 Если вы найдете способ их обнаружить, очень легко добавить синтаксический анализатор событий в библиотеку Visual Event. Заходите, код отличный :)

Legends
5 ноября 2016 в 12:47
0

У вас также есть проблема, если скрипт минифицирован, все будет в одной строке. Было бы неплохо нажать кнопку копирования. Также всплывающее окно VE мешает мне, когда я наводю курсор на элементы ... Но, тем не менее, это очень полезное расширение!

Justin Farrugia
2 августа 2019 в 10:01
0

@TonyR, вы пришли искать визуализатор событий и жалуетесь, потому что загрузка 17k событий занимает 3 минуты? Я имею в виду, что могу создать AI VisualEvent, который будет смотреть на ваши события и ловить только те, которые вам понадобятся в конкретное время, только если вы хотите ...

Elijah Mock
7 декабря 2019 в 23:40
0

В чем разница между визуальным событием и визуальным событием 2?

avatar
Gabriel Petersson
22 июля 2020 в 14:22
12

Чтобы все прослушиватели событий на странице печатались вместе с их элементами

Array.from(document.querySelectorAll("*")).forEach(e => {
    const ev = getEventListeners(e)
    if (Object.keys(ev).length !== 0) console.log(e, ev)
})
avatar
Aiden Waterman
18 апреля 2019 в 14:57
1

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

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

прочтите остальных слушателей с помощью

console.log(someElement.onclick);
console.log(someElement.getAttribute("onclick"));
avatar
akinuri
28 июня 2018 в 09:21
4

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

Во-первых, мне нужен контейнер для всех прослушивателей событий на странице: это объект 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://coderhelper.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, требуется дальнейшая модификация. Я могу исправить это в будущем.

avatar
T.Todua
28 февраля 2017 в 15:13
3

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

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

avatar
Jon z
6 ноября 2015 в 17:49
24

Вы можете обернуть собственные методы 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>

H / T @ les2

Maciej Krawczyk
3 февраля 2017 в 17:25
0

Пожалуйста, поправьте меня, если я ошибаюсь, но разве это не только для прослушивателей событий, прикрепленных к окну?

Jon z
6 февраля 2017 в 16:47
0

@MaciejKrawczyk да, и те, что пузырились

avatar
n00b
27 июня 2015 в 10:47
12

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

David Bradshaw
24 августа 2015 в 19:55
3

Это хороший ответ, но я не могу заставить его работать с элементами body и document.

Dzhakhar Ukhaev
21 января 2017 в 10:56
0

Действительно хорошее решение!

n00b
29 января 2017 в 12:11
0

@ Питер Мортенсен, почему ты сменил имя Яна? :)

Stefan Steiger
21 июля 2018 в 15:04
2

@ Дэвид Брэдшоу: потому что тело, документ и окно имеют свой собственный прототип, а не прототип элемента ...

Stefan Steiger
23 июля 2018 в 00:01
1

@ n00b: есть ошибка. Вот почему хммм. Вы используете оператор-запятую в операторе if для слушателя и useCaption ... Оператор-запятая оценивает каждый из своих операндов (слева направо) и возвращает значение последнего операнда. Таким образом, вы удаляете первый eventListener, который соответствует useCapture, независимо от типа события ... Это должно быть && вместо запятой.

avatar
Joel Barba
19 мая 2015 в 08:33
3

Я пытаюсь сделать это в 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>
avatar
simonzack
14 января 2015 в 15:33
18

Инструменты разработчика Firefox теперь делают это. События отображаются при нажатии кнопки «ev» справа от дисплея каждого элемента, включая события jQuery и DOM.

Screenshot of Firefox developer tools' event listener button in the inspector tab

Eric
3 февраля 2015 в 21:07
0

Я посмотрел на один из элементов dom на странице, на которой букмарклет Visual Event 2 показывает связанное с событием событие, и увидел маленькую кнопку «ev» справа, как вы показываете.

Nick Tsai
4 августа 2017 в 06:31
0

Слушатель событий Firefox может обнаруживать события, делегированные jQuery, в то время как Chrome нужен плагин для этого.

avatar
Jan Turoň
3 апреля 2014 в 15:08
31

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);
  };
})();

Прочитать все события от:

var clicks = someElement.eventListenerList.click;
if(clicks) clicks.forEach(function(f) {
  alert("I listen to this function: "+f.toString());
});

И не забудьте переопределить Element.removeEventListener, чтобы удалить событие из пользовательского Element.eventListenerList.

3: свойство Element.onclick требует особого ухода:

if(someElement.onclick)
  alert("I also listen tho this: "+someElement.onclick.toString());

4: не забудьте атрибут содержимого Element.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 (упомянутый в самом популярном ответе) крадет только кеш обработчика пользовательской библиотеки:

Оказывается, не существует стандартного метода, предоставляемого W3C. рекомендуемый интерфейс DOM, чтобы узнать, какие прослушиватели событий прикреплен к определенному элементу. Хотя это может показаться надзора, было предложение включить недвижимость под названием eventListenerList до спецификации DOM уровня 3, но был к сожалению, был удален в более поздних версиях. Таким образом, мы вынуждены посмотрели на отдельные библиотеки Javascript, которые обычно поддерживать кеш прикрепленных событий (чтобы их можно было позже удалить и выполнять другие полезные абстракции).

Таким образом, чтобы визуальное событие отображало события, оно должно иметь возможность анализировать информацию о событии из библиотеки Javascript.

Переопределение элемента может быть сомнительным (например, потому что есть некоторые специфические функции DOM, такие как живые коллекции, которые не могут быть закодированы в JS), но он дает поддержку eventListenerList изначально и работает в Chrome, Firefox и Opera (не работать в IE7).

avatar
Pranay Soni
19 марта 2014 в 09:30
57

Используйте getEventListeners в Google Chrome :

getEventListeners(document.getElementByID('btnlogin'));
getEventListeners($('#btnlogin'));
Bryan Grace
18 ноября 2015 в 22:43
2

Uncaught ReferenceError: getEventListeners не определен

Nickolay
13 февраля 2016 в 13:20
6

getEventListeners работает только в консоли разработчика Chrome. И это дубликат этого более подробного ответа: coderhelper.com/a/16544813/1026

avatar
Daniel Sokolowski
28 ноября 2013 в 16:30
8

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

enter image description here

avatar
Raghav
14 мая 2013 в 13:40
475

Chrome, Firefox, Vivaldi и Safari поддерживают getEventListeners(domElement) в своей консоли Developer Tools.

Для большинства целей отладки это можно использовать.

Ниже очень хорошее руководство по его использованию: https://developers.google.com/web/tools/chrome-devtools/console/utilities#geteventlisteners

Grault
19 августа 2013 в 05:54
2

+1. Код, специфичный для браузера, для меня не проблема, потому что я пытаюсь получить некорректную работу страницы, которую не контролирую.

gillyspy
20 декабря 2013 в 16:25
13

приятно, но работает только в командной строке консоли Chrome :(

jave.web
14 марта 2015 в 00:23
0

В каких версиях Chrome это доступно, потому что 40 вроде бы его нет ...

Raghav
14 марта 2015 в 04:08
0

@ jave.web Сейчас я использую 41.0.2272.89. Функция все еще существует.

jave.web
15 марта 2015 в 19:53
8

@Raghav ах, спасибо, использование getEventListeners(object) НЕ: obj getEventListeners() как я сначала подумал :)

doABarrelRoll721
20 февраля 2016 в 05:06
20

Вы могли бы сэкономить мне 3 часа, если бы объяснили, как получить исходный код слушателя событий. Эта «ссылка» ничего не объясняла. Если кто-то еще потерпел убыток, вот как: var list = getEventListeners(document.getElementById("YOURIDHERE")); console.log(list["focus"][0]["listener"].toString()). Измените «фокус» на событие, которое вы хотите проверить, и число, если у одного и того же события есть несколько слушателей.

cacoder
31 января 2017 в 23:46
80

СОВЕТ: getEventListeners($0) получит прослушиватели событий для элемента, на котором вы сосредоточились в инструментах разработчика Chrome. Я использую это все время. Мне нравится не использовать функции querySelector или get__By_

jeromej
2 июля 2017 в 21:05
0

@CliffordFajardo Похоже, это хорошая скрытая функция. <3

Franklin Yu
14 июня 2018 в 23:01
0

Как oriadam упомянул в своем комментарии, внутренние инструменты разработчика Chrome и Firefox (F12) имеют встроенную программу просмотра событий.

xgqfrms
10 апреля 2021 в 15:41
0

отличное решение, спасибо большое!

avatar
Ronald
17 января 2013 в 17:28
4

Прототип 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];
}
avatar
Luke
22 октября 2012 в 19:04
43

(Переписывая ответ из на этот вопрос, поскольку он здесь актуален.)

При отладке, если вы просто хотите видеть события, я рекомендую либо ...

  1. Визуальное событие
  2. Раздел Элементы инструментов разработчика Chrome: выберите элемент и найдите «Слушатели событий» в правом нижнем углу (аналогично Firefox)

Если вы хотите использовать события в своем коде, и вы используете jQuery до версии 1.8 , вы можете использовать:

$(selector).data("events")

, чтобы получить события. Начиная с версии 1.8 использование .data ("событий") больше не поддерживается (см. этот билет об ошибке). Вы можете использовать:

$._data(element, "events")

Другой пример: записывать все события щелчка по определенной ссылке в консоль:

var $myLink = $('a.myClass');
console.log($._data($myLink[0], "events").click);

(рабочий пример см. http://jsfiddle.net/HmsQC/)

К сожалению, с использованием данных $ ._ это не рекомендуется , за исключением отладки, поскольку это внутренняя структура jQuery и может измениться в будущих выпусках. К сожалению, я не знаю других простых способов доступа к событиям.

Marius Gedminas
6 декабря 2013 в 11:19
1

$._data(elem, "events") не работает с jQuery 1.10, по крайней мере, для событий, зарегистрированных с использованием $(elem).on('event', ...). Кто-нибудь знает, как их отлаживать?

Luke
6 декабря 2013 в 20:44
4

Я не уверен, но я думаю, что первый параметр $._data может быть элементом, а не объектом jQuery. Поэтому мне нужно исправить мой пример выше, чтобы он был console.log($._data($myLink[0], "events").click);

avatar
Ivan Castellanos
22 июня 2011 в 04:32
77

Можно перечислить все прослушиватели событий в 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});
};

Теперь каждый элемент привязки (a) будет иметь свойство lastListenerInfo, которое содержит всех его слушателей. И это даже работает для удаления слушателей с анонимными функциями.

huyz
25 июля 2011 в 08:22
5

Этот метод не будет работать, если вы пишете пользовательский сценарий или сценарий содержимого. В наши дни не только могут быть изолированы в песочнице, но и как вы можете гарантировать порядок выполнения?

Tzury Bar Yochay
1 июня 2012 в 05:54
0

этот метод работает с chrome / 19 и FF / 12. порядок выполнения может быть гарантирован, если вы подключите его до других скриптов

Esailija
16 июня 2012 в 06:48
10

Не могли бы вы вместо этого просто изменить Node.prototype? Вот где HTMLAnchorElement в любом случае наследует .addEventListener ».

RobG
13 ноября 2012 в 00:43
3

Вы предполагаете, что пользовательский агент реализует наследование прототипов для хост-объектов DOM и позволяет вам изменять их. Ни одна из этих идей не является хорошей: не изменяйте объекты, которыми вы не владеете.

gotofritz
15 сентября 2015 в 10:46
1

Это довольно бесполезно - оно показывает, какие слушатели событий были добавлены, что в некоторых случаях может быть полезно, но не то, что было удалено. Так что, если вы пытаетесь отладить, что было удалено, а что нет, просто нет способа.

doABarrelRoll721
20 февраля 2016 в 04:48
0

@gotofritz прав. Это не показывает вам прослушивателей событий, которые у вас есть на данный момент. Интересно, читали ли поддерживающие вообще вопрос.

Ivan Castellanos
20 февраля 2016 в 23:51
0

@ doABarrelRoll721 И мне интересно, есть ли у вас здравый смысл. Видите ли, JavaScript выполняется на стороне браузера, поэтому вы можете выполнить его в любой момент, когда захотите, например с небольшой помощью tamper-monkey вы можете запускать на всех веб-сайтах, которые вы открываете.

doABarrelRoll721
21 февраля 2016 в 01:12
0

@IvanCastellanos Я имел в виду, что ваш массив lastListenerInfo содержит только добавленных слушателей . OP запросил , какие прослушиватели событий наблюдают за конкретным узлом DOM , включая те, которые были удалены . Если бы вы перезаписали removeEventListener так же, как вы сделали с addEventListener, ваш массив lastListenerInfo будет иметь именно то, что просил OP (хотя он говорил о вводе и выборе элементов, а не о якорях, а о чем угодно).

avatar
Ishan
17 января 2011 в 07:39
95

WebKit Inspector в браузерах Chrome или Safari теперь делает это. Он отобразит прослушиватели событий для элемента DOM, когда вы выберете его на панели «Элементы».

huyz
25 июля 2011 в 08:21
9

Я не уверен, что он показывает все обработчики событий; только единственный обработчик событий HTML.

Nickolay
18 октября 2011 в 22:59
3

Для полноты картины я должен упомянуть плагин EventBug для Firebug <softwareishard.com/blog/category/eventbug>

siliconrockstar
19 декабря 2013 в 17:41
0

Это просто сделало мой день, у некоторого устаревшего кода прототипа было несколько функций, привязанных к одному и тому же событию в одном и том же элементе, и я умирал, пытаясь отследить их. Большое спасибо, Ишан.

avatar
Michael Butler
7 января 2010 в 22:52
12

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

Попробуйте:

console.dir(clickEvents);

или

console.dir(window);
Javier Constanzo
31 августа 2013 в 15:31
9

Новая функция в firebug 1.12 getfirebug.com/wiki/index.php/GetEventListeners

avatar
Crescent Fresh
15 января 2009 в 15:13
383

Это зависит от того, как прикреплены события. Для иллюстрации предположим, что у нас есть следующий обработчик кликов:

var handler = function() { alert('clicked!') };

Мы собираемся прикрепить его к нашему элементу, используя разные методы, некоторые из которых позволяют проверку, а некоторые нет.

Метод A) обработчик одиночного события

element.onclick = handler;
// inspect
console.log(element.onclick); // "function() { alert('clicked!') }"

Метод Б) несколько обработчиков событий

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 (хранит обработчик внутри объекта)

     // 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+ (очень красиво)

    Сделано с использованием знаний из этого комментария.

     events = $._data(this, 'events');
     for (type in events) {
       events[type].forEach(function (event) {
         console.log(event['handler']);
       });
     }
    

(см. jQuery.fn.data и jQuery.data)<09392> <37173

Метод 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 до 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){
         console.log(wrapper.handler) // "function() { alert('clicked!') }"
     })
    
  • 1.6.1 (немного лучше)

     // inspect
     var clickEvents = element.getStorage().get('prototype_event_registry').get('click');
     clickEvents.each(function(wrapper){
         console.log(wrapper.handler) // "function() { alert('clicked!') }"
     })
    

Если щелкнуть полученный результат в консоли (который показывает текст функции), консоль перейдет непосредственно к строке объявления функции в соответствующем файле JS.

Keith Bentrup
14 сентября 2009 в 18:35
3

Спасибо за обновление. К сожалению, вам приходится перебирать каждый тип обработчика.

Nickolay
18 октября 2011 в 23:00
4

В «Методе B» (addEventListener) вот ответ относительно статуса средств перечисления для обработчиков, зарегистрированных с помощью чистого API событий DOM: coderhelper.com/questions/7810534/…

Crescent Fresh
25 апреля 2012 в 01:23
0

@John: спасибо за комментарий. У вас есть пример «настоящего JavaScript» для получения слушателей, ранее добавленных через addEventListener?

John
25 апреля 2012 в 17:23
0

Если кто-то неаккуратен, он может создать службу мониторинга. Если у них есть хорошие практики, им просто не нужно их создавать. Те же слушатели перезаписывают старые версии самих себя.

tomdemuyt
30 мая 2012 в 18:26
7

@Jan, похоже, это не работает для jQuery 1.7.2, есть ли другой подход для этой версии?

Aaron
12 января 2013 в 18:24
0

А как насчет прослушивателей событий, которых нет в фактическом элементе, например, следующего: $(parentElement).on(event, 'myElement', handler);?

Rolf
12 января 2014 в 09:06
0

Почему существует так много способов прикрепить события и так много мест, где их можно сохранить? Нам, программистам, это не очень помогает, не так ли?

Matt Browne
13 февраля 2014 в 16:17
15

@tomdemuyt В jQuery события теперь хранятся во внутреннем массиве данных, а не доступны через .data('events'), как раньше. Для доступа к внутренним данным событий используйте $._data(elem, 'events'). Обратите внимание, что эта функция помечена как «только для внутреннего использования» в источнике jQuery, поэтому нет никаких обещаний, что она всегда будет работать в будущем, но я считаю, что она работала с момента выхода jQuery 1.7 и все еще работает.

mbomb007
25 сентября 2020 в 21:46
0

@MattBrowne Очень мило. Я добавил его к ответу как полное решение.