Как отлаживать привязки событий JavaScript / jQuery с помощью Firebug или аналогичных инструментов?

609

Мне нужно отладить веб-приложение, которое использует jQuery для выполнения довольно сложных и грязных манипуляций с DOM . В какой-то момент некоторые события, которые были связаны с определенными элементами, не запускаются и просто перестают работать.

Если бы у меня была возможность редактировать исходный код приложения, я бы развернул и добавил кучу операторов Firebug console.log() и комментировал / раскомментировал фрагменты кода, чтобы попытаться точно определить проблему. Но давайте предположим, что я не могу редактировать код приложения и должен работать полностью в Firefox, используя Firebug или аналогичные инструменты.

Firebug очень хорошо позволяет мне ориентироваться и манипулировать DOM. Однако до сих пор я не смог понять, как выполнять отладку событий с помощью Firebug. В частности, я просто хочу увидеть список обработчиков событий, привязанных к определенному элементу в данный момент времени (используя точки останова Firebug JavaScript для отслеживания изменений). Но либо Firebug не способен видеть связанные события, либо я слишком туп, чтобы его найти. :-)

Любые рекомендации или идеи? В идеале я просто хотел бы видеть и редактировать события, связанные с элементами, подобно тому, как я могу редактировать DOM сегодня.

Яанус
источник

Ответы:

355

См. Как найти слушателей событий на узле DOM .

В двух словах, если предположить, что в какой-то момент к вашему элементу присоединен обработчик событий (например): $('#foo').click(function() { console.log('clicked!') });

Вы проверяете это так:

  • jQuery 1.3.x

    var clickEvents = $('#foo').data("events").click;
    jQuery.each(clickEvents, function(key, value) {
      console.log(value) // prints "function() { console.log('clicked!') }"
    })
  • jQuery 1.4.x

    var clickEvents = $('#foo').data("events").click;
    jQuery.each(clickEvents, function(key, handlerObj) {
      console.log(handlerObj.handler) // prints "function() { console.log('clicked!') }"
    })

Смотрите jQuery.fn.data(где jQuery хранит ваш обработчик внутри).

  • jQuery 1.8.x

    var clickEvents = $._data($('#foo')[0], "events").click;
    jQuery.each(clickEvents, function(key, handlerObj) {
      console.log(handlerObj.handler) // prints "function() { console.log('clicked!') }"
    })
Свежий полумесяц
источник
21
К вашему сведению: это не будет отображать события, которые не были связаны с JQuery
Хуан Мендес
10
Полностью согласен с console.log (), однако он должен быть застрахован чем-то вроде того, if (window.console)на случай, если он останется в коде (гораздо проще сделать, чем с alert ()) и сломает IE.
thepeer
14
@thepeer Лично я предпочитаю проверять консоль в начале файла и, если она не существует, создать фиктивный объект.
Андрей
Ниже приведен похожий фрагмент для отладки всех событий (прошу прощения за отсутствие форматирования):$('#foo').click(function(event) { var events = $(this).data('events'); $.each(events, function(event, handlers) { $.each(handlers, function(key, handlerObj) { console.log("--------------------------------------"); console.log(event+"["+key+"] | "+handlerObj.handler) ; }); });
Кори О.
3
@ BrainSlugs83: см. Связанный ответ в этом ответе. (TL; доктор: вы не можете).
Crescent Fresh
162

Есть хороший букмарклет Visual Event, который может показать вам все события, прикрепленные к элементу. Он имеет цветную подсветку для различных типов событий (мышь, клавиатура и т. Д.). При наведении на них курсора отображается тело обработчика события, способ его подключения и номер файла / строки (в WebKit и Opera). Вы также можете вызвать событие вручную.

Он не может найти каждое событие, потому что нет стандартного способа узнать, какие обработчики событий прикреплены к элементу, но он работает с популярными библиотеками, такими как jQuery, Prototype, MooTools, YUI и т. Д.

Мэтью Крамли
источник
8
Обратите внимание, что, поскольку он выполняется в содержимом JavaScript, он получает свои данные, запрашивая библиотеки JavaScript. Таким образом, он будет отображать только события, добавленные с помощью поддерживаемой библиотеки (которая включает в себя jQuery).
Мэтью Флэшен
41

Вы можете использовать FireQuery . Он показывает любые события, прикрепленные к элементам DOM на вкладке HTML в Firebug. Он также показывает любые данные, прикрепленные к элементам через $.data.

Шрикант Шарат
источник
1
У этого плагина есть один действительно большой недостаток: когда вы отлаживаете и хотите проверить значение переменной, содержащей коллекцию jquery, вы не можете проверить это значение, когда ваш код приостановлен. Это не причина с firebug. Причина для меня, чтобы удалить его. один
Мартен Кифт
1
FireQuery, похоже, больше не показывает прикрепленные события :(
Matty J
26

Вот плагин, который может перечислить все обработчики событий для любого данного элемента / события:

$.fn.listHandlers = function(events, outputFunction) {
    return this.each(function(i){
        var elem = this,
            dEvents = $(this).data('events');
        if (!dEvents) {return;}
        $.each(dEvents, function(name, handler){
            if((new RegExp('^(' + (events === '*' ? '.+' : events.replace(',','|').replace(/^on/i,'')) + ')$' ,'i')).test(name)) {
               $.each(handler, function(i,handler){
                   outputFunction(elem, '\n' + i + ': [' + name + '] : ' + handler );
               });
           }
        });
    });
};

Используйте это так:

// List all onclick handlers of all anchor elements:
$('a').listHandlers('onclick', console.info);

// List all handlers for all events of all elements:
$('*').listHandlers('*', console.info);

// Write a custom output function:
$('#whatever').listHandlers('click',function(element,data){
    $('body').prepend('<br />' + element.nodeName + ': <br /><pre>' + data + '<\/pre>');
});

Источник: (мой блог) -> http://james.padolsey.com/javascript/debug-jquery-events-with-listhandlers/

Джеймс
источник
11

Используйте $._data(htmlElement, "events")в jquery 1.7+;

например:

$._data(document, "events") или $._data($('.class_name').get(0), "events")

Тамас Пап
источник
8

Как предложил коллега, console.log> alert:

var clickEvents = $('#foo').data("events").click;
jQuery.each(clickEvents, function(key, value) {
    console.log(value);
})
Flevour
источник
6

jQuery хранит события в следующем:

$("a#somefoo").data("events")

Выполнение console.log($("a#somefoo").data("events"))должно перечислить события, прикрепленные к этому элементу.

Алекс Хейд
источник
5

Используя DevTools в последней версии Chrome (v29), я считаю эти два совета очень полезными для отладки событий:

  1. Вывод списка событий jQuery последнего выбранного элемента DOM

    • Осмотреть элемент на странице
    • введите в консоли следующее:

      $ ._ data ( $ 0 , "events") // предполагается, что jQuery 1.7+

    • В нем будут перечислены все объекты события jQuery, связанные с ним, развернуто интересующее событие, щелкните правой кнопкой мыши функцию свойства «обработчик» и выберите «Показать определение функции». Откроется файл, содержащий указанную функцию.

  2. Использование команды monitorEvents ()

mateuscb
источник
4

Похоже, команда FireBug работает над расширением EventBug. Это добавит еще одну панель в FireBug - События.

«На панели событий будут перечислены все обработчики событий на странице, сгруппированные по типу события. Для каждого типа события вы можете открыть список элементов, к которым привязаны слушатели, и краткую информацию об источнике функции». EventBug Rising

Хотя прямо сейчас они не могут сказать, когда он будет выпущен.

jayarjo
источник
2
Эта функция была выпущена и включена в FireBug 2.0.1. Теперь, когда вы проверяете HTML-элемент на странице, появляется новая панель «События», где вы можете увидеть прикрепленные события и их обработчики.
derloopkat
4

Я также нашел jQuery Debugger в магазине Chrome. Вы можете нажать на элемент DOM, и он покажет все события, связанные с ним вместе с функцией обратного вызова. Я отлаживал приложение, в котором события не удалялись должным образом, и это помогло мне отследить его за несколько минут. Очевидно, что это для Chrome, а не Firefox.

обкрадывать
источник
4

ev значок рядом с элементами

На панели « Инспектор» инструментов разработчика Firefox перечислены все события, связанные с элементом.

Сначала выберите элемент с помощью Ctrl+ Shift+ C, например, стрелка вверх переполнения стека.

Нажмите на evиконку справа от элемента, и откроется диалоговое окно:

всплывающая подсказка о событиях

Нажмите на ||символ знака паузы для желаемого события, и это откроет отладчик в строке обработчика.

Теперь вы можете поместить точку останова там, как обычно, в отладчике, нажав на левое поле строки.

Это упоминается по адресу: https://developer.mozilla.org/en-US/docs/Tools/Page_Inspector/How_to/Examine_event_listeners

К сожалению, я не мог найти способ, чтобы это хорошо сочеталось с симпатичной игрой, просто кажется, что она открывается на минимизированной строке: как украсить Javascript и CSS в Firefox / Firebug?

Протестировано на Firefox 42.

Ciro Santilli 郝海东 冠状 病 六四 事件 法轮功
источник
К сожалению, это плохо работает для поиска наследуемых слушателей.
chukko
3

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

Похоже, что лучшее, что вы можете сделать, это либо то, что предлагает tj111, либо вы можете щелкнуть правой кнопкой мыши элемент в средстве просмотра HTML и нажать «Журнал событий», чтобы вы могли увидеть, какие события запускаются для конкретного элемента DOM. Я полагаю, можно было бы сделать это, чтобы увидеть, какие события могут запускать определенные функции.

Дэн Лью
источник
2

В версии 2.0 Firebug представил панель « События» , в которой перечислены все события для элемента, выбранного в данный момент на панели HTML .

* События * Боковая панель в Firebug

Он также может отображать прослушиватели событий, обернутые в привязки событий jQuery, в случае, если установлен флажок Show Wrapped Listeners , доступ к которому можно получить через меню параметров панели « События » .

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

  1. Выберите элемент с прослушивателем событий, который вы хотите отладить
  2. Внутри боковой панели « События» щелкните правой кнопкой мыши функцию под связанным событием и выберите « Установить точку останова».
  3. Запустить событие

=> Выполнение скрипта остановится на первой строке функции-обработчика события, и вы можете пошагово отлаживать его.

Себастьян Зартнер
источник
0

Firebug 2 теперь включает отладку / проверку событий DOM.

MRalwasser
источник