Ted Mosby @TedMosby read-only
Пользователь
27 апреля 2012 в 00:01

Разработка → Внутренности jQuery. Поиск кода, выполняемого по событию

Чем дальше в лес, тем толще партизаны. Нет, не так. Чем старше веб, тем больше джаваскрипта

Клиентского кода в веб-приложениях с каждым годом действительно становится все больше. Подчас это десятки файлов с сотнями функций. И что делать, когда нам нужно поменять код, выполняемый по событию (например, клик по ссылке). Как его найти? Задавшись решением этой задачи, я придумал несколько разных вариантов. Каждый из них имеет свои плюсы и минусы. И в конце статьи я предлагаю метод, который мне кажется оптимальным.

Формулировка задачи


Сразу скажу, заголовок отражает суть вопроса: мы ищем обработчик события, который был добавлен с использованием библиотеки jQuery, которая сейчас очень популярна. Для демонстрации вариантов решения мы будем использовать Инструменты Разработчика Google Chrome, так как они предоставляют некоторые продвинутые возможности, которых нет в консолях других браузеров. Без этих фишек некоторые варианты решения не представляются возможными вообще.

Подопытный кролик


Искать код обработчика событий мы будем на главной странице Яндекса. Главным образом потому, что он использует jQuery. Не очень новой версии, правда — 1.4, но не суть. В этот раз нас будет интересовать, какой код выполняется при нажатии на ссылку «Сделать Яндекс стартовой страницей». Найти — это значит узнать имя файла скрипта, номер строки. И конечно увидеть сам код.

Метод №1


Используя Инструменты Разработчика Google Chrome (F12), все что нужно сделать — это кликнуть по ссылке правой кнопкой, выбрать «Просмотр кода элемента», щелкнуть по вкладочке «Event Listeners» справа и увидеть там все обработчики событий. Проблема при использовании jQuery в том, что в этом случае этот код будет ничем иным, как куском внутренностей jQuery.

Достоинства

  • в простых случаях это работает

Недостатки

  • если используется jQuery, этот способ малоэффективен
  • если обработчик вешается через live(), то он просто не покажется в списке


Поставим брейкпойнт на событие


Богатый функционал Инструментов Разработчика Google Chrome предоставляет нам возможность ставить брейкпойнты на любые события. Открываем консоль (F12), выбираем вкладку «Scripts», разворачиваем «Event Listener Breakpoint», ставим брейкпойнт на Mouse.click. Кликаем по ссылке, попадаем в какой-то внутренний орган jQuery — скорее всего в ЖКТ. В некоторых случаях этот способ эффективен, и мы сразу можем увидеть вызываемый код. Но только не в этом. Как из этого места добраться до искомого кода — честно говоря, не знаю.

Достоинства

  • иногда срабатывает

Недостатки

  • в этот раз не сработало
  • если обработчиков навешано несколько, мы сможем отловить только первый из них, остальные мы так и не найдем


Если мы что-то знаем


Так случается, что иногда о нужном куске кода мы что-то знаем заранее. Например, по нажатию кнопки она становится другого цвета. В этом случае есть один метод. Щелкаем правой кнопкой на элементе, выбираем «Просмотр кода элемента», кликаем по найденному в иерархии DOM элементу правой кнопкой и выбираем «Break on attributes modifications». Остается только нажать ссылку — и мы попадаем в искомый кусок кода.

Достоинства

  • быстрота получения решения

Недостатки

  • применить можно далеко не всегда, решение не универсально


Используем расширение Chrome


Есть такое замечательное расширение Chrome — Visual Event, которое на первый взгляд творит просто чудеса. Достаточно кликнуть на нужной странице иконку расширения — и для каждого элемента покажутся все обработчики на них навешанные. При наведении на иконку события, можно увидеть выполняемый по событию код.

Достоинства

  • очень просто использовать
  • показывает все, что нужно

Недостатки

  • нужно дополнительно что-то устанавливать
  • на страницах со сложной версткой многие иконки окажутся просто недоступными для просмотра
  • задача все-таки не решается до конца: код-то мы увидели, но в каком файле и на какой строке он находится, мы не знаем


Можно обойтись и без расширения


Тру-хакерам достаточно в консоли Javascript написать $(selector).data('events') и можно увидеть все обработчики, прицепленные к элементу. Если обработчик вешается через live(), то нужно вывести $(document).data('events') и поискать в списке искомый. Однако, как и в случае с расширением, этот метод не решает задачу до конца, и при этом нужно довольно долго искать нужный обработчик.

Наконец-то


Что же предлагаю я как оптимальное решение задачи?

  1. Открываем Инструменты Разработчика Google Chrome (F12), выбираем вкладку «Scripts» и находим в выпадающем списке скрипт jQuery.
  2. Щелкаем кнопочку «Pretty print» для эстетики.
  3. Находим обработчик событий jQuery введя в поиске «handle:». Двоеточие в конце ставится для того, чтобы сразу перейти к объявлению функции. В более новых версиях библиотеки эта функция называется dispatch, но не суть. Эта функция является точкой, через которую проходят все назначенные события. Там хватает кода, нам важна строка, где есть вызов apply — это по сути и есть вызов нашего искомого куска кода.
  4. Событий через функцию проходит много, поэтому ставим не обычный брейкпойнт, а условный. Первым параметром функции является объект события, поэтому пишем «arguments[0].type=='click'».
  5. Кликаем по ссылке и срабатывает брейкпойнт на нашей строчке.
  6. Чтобы перейти к искомому куску кода, жмем «Step into next function call» (F11). Вуаля! Мы не только нашли нужный кусок кода, мы еще и знаем теперь в каком файле и на какой строчке он находится. Задача решена. Прекрасно.
  7. Если обработчиков несколько, последовательно нажимая F8 F11, добираемся до нужного.

Достоинства

  • действительно решает поставленную задачу
  • задача решается стандартными инструментами
  • метод универсальный

Недостатки

  • мозг должен быть включенным

Ted Mosby @TedMosby
карма
0,0
рейтинг 0,0
Реклама помогает поддерживать и развивать наши сервисы

Подробнее
Спецпроект

Самое читаемое Разработка

Комментарии (34)

  • –30
    >>Чем старше веб, тем больше джаваскрипта

    а чем больше джаваскрипта, тем больше глюков
    • +2
      Спорно, когда приложение частично генерит информацию на стороне сервера, а ее дополняет js получаются такие забавные глюки, что шерсть встает дыбом. Для веб-приложений лучше сразу делать фукционал на js, для пользователя это будет удобнее и адекватнее в плане поведения.
    • +5
      Фигню сморозили
    • +9
      Можно экстраполировать вашу мысль: чем больше кода, тем больше глюков.
      И вывести следствие: идеальный код без глюков — отсутствие кода.
    • +1
      Код можно исправить, а проблемы с безопасностью решать гораздо сложнее.
      Аплеты, флеш уходят, все приводится к единому знаменателю. Меня лично это радует.

  • +9
    << Тру-хакерам достаточно в консоли Javascript написать $(selector).data('events')
    Опустили звание хакера до фантика
    • +4
      Это же шутка :)
      Имеется в виду по сравнению с теми, кто использует расширение с графическим интерфейсом.
      • +5
        Я часто использую консоль хрома вместо калькулятора, или чтобы найти длину строки, а вы так шутите… :)
        • 0
          там же не удобно. У меня для этого Scheme стоит.
    • 0
      Если событие установлено через live()/delegate()/on() не на самом элементе, а на родительском (или даже оно будет всплывать до body), то через $(selector).data('events') мы ничего не узнаем. Узнаем только на элементе, до которого всплывает событие. Соответственно, будет что-то типа такого:

      {
          click : [
              0: { ... }
          ],
          live : [
              0: { ... }
          ]
      }
      

      Причём в click.0.origHandler будет ссылка на функцию из секции live (live.0.handler).
  • +16
    Неплохо, очень неплохо. И про некоторые ранее неведомые возможности Chrome devtool узнала! Благодарю!
  • +1
    Метода прекрасно работает и в FF+Firebug, разве что проверять на главной Яндекса бесполезно, в какие-то дебри уводит. Спасибо:)
    • 0
      У меня почему-то наоборот, в Хроме уводит, а в Файрфоксе появляется всплывающее окно.
      • 0
        После выполнения шага 6 у вас должен быть код, изображенный на последней картинке. У вас что-то другое? Можно посмотреть?
  • +2
    Вместо установки расширения Visual Event можно вытащить на панель закладок ссылку с сайта разработчика. Работает, как минимум, в ФФ и хроме.
  • +6
    Для firefox есть отличное дополнение — fireQuery. Сразу во вкладке с кодом показываются навешены ли события на элемент и если да, то можно легко пройти до функции, которая на него навешена.

    • 0
      У вас получилось найти код, изображенный на последней картинке? У меня что-то не выходит...(
      • +1
        Нажимаете на events > выпадает список всех событий > выбираете нужное и кликаете на его функцию handler. Единственное, что у firebug нет «pretty print», как в chrome, поэтому с инлайновыми скриптами встроенными прямо в страницу проблема и найти этот скрипт в одной строке достаточно сложно =/ Нормального форматера я, к сожалению, не нашел
  • 0
    мы ищем обработчик события, который был добавлен с использованием библиотеки jQuery, которая сейчас очень популярна
    == ищем потерянные ключи под фонарём, потому что там светлее. Но через Хром можно искать любые события. Правда, только сработавшие. Если действительно ограничиваться jQuery, то в Fx есть давно FireQuery, показывающий все места, на которые повешены обработчики.
  • +3
    > Кликаем по ссылке, попадаем в какой-то внутренний орган jQuery — скорее всего в ЖКТ. В некоторых случаях этот способ эффективен, и мы сразу можем увидеть вызываемый код. Но только не в этом. Как из этого места добраться до искомого кода — честно говоря, не знаю.

    Всё довольно просто на самом деле. Включаем pretty print (для удобства) и кликаем на F11 (step into next function call), пока не выйдем из jquery и не попадём в вызванный им обработчик.
  • +2
    задача все-таки не решается до конца: код-то мы увидели, но в каком файле и на какой строке он находится, мы не знаем

    Сам был очень удивлён отсутствием этой информации, т.к. в аналогичном расширении для Opera есть и название файла и номер строки.
    • 0
      Прикольно. Оно даже live-эвенты хавает :)
    • 0
      Я вообще был удивлен фразой что такого функционала нет в других браузерах. В опере есть все необходимое чтоб проделать то же самое, вплоть до отлова евентов.
      • 0
        Да-да меня тоже это насторожило.
        Но, согласитесь, в Dragonfly нету:
        1. «Break on * modifications». И вообще DOM-дерево в отладчике не живое. И непонятно когда этот функционал появится.
        2. «pretty print». Хотя, скоро должен появится.
        • 0
          3. «Event Listeners» тоже нету, что меня лично, часто использующего нативный addEventListener, сильно удручает.
  • +4
    www.youtube.com/watch?feature=player_embedded&v=N8SS-rUEZPg
    Рекомендую к просмотру
    • 0
      Спасибо. Очень интересно.
  • 0
    Что-то под хабркатом, ничего нету.
  • 0
    Куда статья делась?
  • 0
    Автор — в read-only. Видать, туда и делась :(
    Жаль, очень годная статья была.
    • 0
      Из источников, близких к исходникам, стало известно, что в текст статьи был удален либо автором, либо неведомой силой (не НЛО).

Только зарегистрированные пользователи могут оставлять комментарии. Войдите, пожалуйста.