Подробный гайд по отладке кода на JavaScript в Chrome Devtools. Современная отладка JavaScript

Отладка js и CSS

Изначально эту статью я хотел посвятить только тому, что касается отладки js сценариев. Но после написания, оказалось что, вопрос CSS отладки очень сильно связан с этими же отладчиками, поэтому создавать отдельную статью про CSS отладку просто не имеет смысла.

Javascript сочетает в себе мощность и разнообразие параллельно с примитивной отладкой в браузерах. Постоянно пользоваться функцией alert() - трата драгоценного времени. Поэтому без внешних инструментов отладки выявить ошибку и правильно настроить сценарии у Вас быстро не получится. Сценарии js выполняет браузер, но у самих браузеров инструменты по отладке js скриптов либо отсутствуют, либо настолько примитивные, что ими даже пользоваться не хочется.

CSS отладка - это важная составляющая кросс-браузерности вашего сайта. При верстке дизайна сайта верстальщики тестируют страницы в основных браузерах. Основная цель CSS отладки это одинаковое визуальное отображение страниц сайта во всех основных браузерах.

Под каждый браузер существуют специальные инструменты для отладки js сценариев и одновременно CSS отладки. Эти инструменты - специальные утилиты написанные под конкретный браузер. Поэтому отлаживать свои js скрипты Вам придется только под одним браузером, так как каждый браузер имеет свою утилиту.

Браузер Инструменты для отладки js сценариев
Firebug

Firebug Lite,
Dragonfly Opera 9.5 и выше

Firebug Lite
Существует, также, очень мощный инструмент для разработки и отладки
MS Visual Studio , но этот инструмент очень притормаживает и может выдавать ошибку в течении 5-7 сек.
IE 8 имеет встроенные Developer Tools (для отладки в IE 7 есть режим симуляции)

Самым популярным и удобным инструментом большинство считают Firebug для браузера Firefox. И в практической разработке js сценариев я тоже использую эту утилиту. Из всех представленных выше инструментов Firebug наиболее удобный в использовании и функциональней.


На изображение показана часть консоли Firebug"а.
Вкладка "Консоль " самая важная - на ней построчно отображаются ошибки выявленные во время выполнения js сценариев. В строке отображается причина ошибки, а справа название файла и номер строки. При нажатии на кнопку "Профилировать" она перейдет в нажатое состояние. Если Вы отожмете ее, появится таблица с перечнем функций которые выполняются браузером в реальном режиме. Будет показано названия функций, количество вызовов и время выполнения этих функций за промежуток пока было удержана кнопка "Профилировать ".
Второй по важности можно считать вкладку "Сценарий ". Здесь Вы можете увидеть внутренний код любого выбранного js файла. На вкладке, также доступны такие интересные параметры:


- декомпилировать исходники в eval . Позволяет выводить на экран исходный код скрипта, а не закодированный.
- останавливаться на всех ошибках . Останавливает выполнение скрипта на строках, где выявлена ошибка, с описанием ошибки. Сюда, также, относятся ошибки, которые не являются критическими для выполнения скрипта.
Останавливать выполнение скрипта в любой строке Вы можете и самостоятельно. При этом Вам будет доступен просмотр стека вызовов, где отображаются в хронологическом порядке все выполненные функции до точки остановки скрипта. При остановке скрипта, наведение мышки на любой элемент кода, вызывает всплывающее меню со значением элемента.


Вкладка "Сеть " отображает список загруженных скриптов. Если нажать на любой файл, то будет показана информация про обмен заголовками между браузером и сервером, а также содержимое js скрипта. В строке, также отображается размер и время загрузки скрипта.
Это может быть полезно не только при отладке сценариев, а и для ускорения загрузки страницы. Можно просматривать размеры рисунков, подгружаемых js сценариев и оценивать время затраченное на загрузку каждого элемента страницы. Цветовая гамма загрузки помимо отображения времени на загрузку элемента (страницы), времени DNS запроса и времени HTTP запроса, также показывает время ожидание ответа сервера. Или другими словами, время выполнения кода php.



Кроме всего, Firebug позволяет отслеживать ajax запросы, просматривать заголовки ответов и опять же оценивать время запросов.

Помимо всего Firebug имеет командную строку, которую при желании можно увеличить в окно произвольного размера и в нем вживую писать и сразу выполнять любой js код.
Разработчики Firebug создали специальную версию Firebug Lite, которая позволяет отлаживать js сценарии во всех других основных браузерах (Opera, IE, Safari). Правда эта версия немного урезана, но это все равно лучше чем ничего. Ну, и помимо самой отладки js сценариев, доступны также CSS отладка и структура DOM страницы. Выполнение js событий (onclick, onmousemove и т.д.) позволяет в реальном времени отслеживать изменения в HTML коде страницы и DOM документа. Измененные части html кода мгновенно подсвечиваются.
Если Вы выберите элемент страницы и нажмете на вкладку "Макет", то сможете увидеть как элемент позиционируется на странице, а вкладка "Стиль" отобразит все активные и переопределенные свойства элемента (перечеркнутое свойство).

Свойство переопределяется по последнему установленному значению по приоритетности места его назначения.

Opera Dragonfly

В целом Dragonfly тоже неплохой отладчик, но с первой попытки начать отладку у меня не получилось. При тестовой попытке отладить js сценарий, консоль ошибок почему-то упорно оставалась чистой, хотя в скрипте была допущена синтаксическая ошибка и, принудительно, отображалось окно "Консоль ошибок" с указание строки с ошибкой. Как оказалось, для каждой страницы необходимо было заново перезапускать Dragonfly.

По сути отладка js сценариев в Dragonfly это всего лишь дублирование информации об ошибке в "Консоле ошибок" в консоли самого Dragonfly.


Помимо этого, Dragonfly представляет обширные возможности по CSS отладки страницы. Как по мне, то немного проще для восприятия, чем в Firebug. Помимо позиционирования элемента в странице, Dragonfly предлагает просмотр отдельную вкладку "Рассчитанный стиль" в которой отображается все существующие свойства элемента и вкладку "Стили" со свойствами элемента разбитыми по классам.

Тогда как, Firebug на вкладке "Показать вычисленный стиль" отображает все свойства без цветового оформления. Однако, по сравнению с Firebug, изменение CSS свойств и просмотр изменений в реальном времени в Dragonfly недоступно. Каких-либо особенностей Dragonfly в отличие Firebug по отладке js сценариев нет. Есть также отображение Ajax запросов, заголовки обмена данные между клиентом и сервером, время запроса. Однако указывается лишь полное время запроса без детализации. При работе с Dragonfly складывается впечатление, что он немного притормаживает. Сравнение быстродействия консолей, показало что Dragonfly таки напрягает процессор больше, хоть и незначительно.

К минусам можно отнести то, что для отладки js сценариев не предусмотрено профилирование.

IE Developer Tools

Полный набор инструментов для отладки js сценариев и css отображение свойств элементов страницы. В случае синтаксической или другой ошибки в js сценарии в консоли отображается описание ошибки, название файла и номер строки в которой произошла ошибка.


К особенностям, которых нет в других отладчиках, можно отнести:
- возможность изменять размер страницы под популярные расширения (1024х768, 1280х768б 1280х1024 и другие);
- при профилировании "Создание/Остановка профилей " названия функций, количество вызовов и время выполнения этих функций за промежуток можно вывести в виде дерева. Что позволяет удобно отследить очередность и вложенность вызовов функций. Firebug позволяет выводить только общий список вызванных функций;
- функция "вид -> источник -> исходный код элемента со стилем" выводит в отдельном окне html код выделенного элемента вместе со всеми это css стилями. Это может быть особенно полезно, если Вам вдруг понадобится взять с другого сайта часть страницы вместе с сss стилями.
К минусам можно отнести то, что в IE Developer Tools отсутствует панель для отслеживания запросов, поэтому отследить количество запросов и скорость загрузки не получится.
Как известно, IE это самый отстающий от спецификаций браузер. При верстке дизайна IE больше всех требует внимания и поиска решений для правильного отображения элементов страницы. Поэтому к большому плюсу IE Developer Tools можно отнести возможность проверять совместимость страницы в IE 7.


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


Вот пожалуй и все, с основными отладчиками js сценариев и CSS Вы ознакомились. Более детально описывать я не вижу смысла, ведь большинство возможностей обычно не используются. Все отладчики имеют русскоязычный интерфейс и с упущенными деталями Вы сможете разобраться самостоятельно без особых затруднений. Удачи Вам.

1074

Здравствуйте! В продолжении темы поговорим об отладке скриптов силами браузера. Для примера возьмем самый лучший браузер на Земле — Chrome.

В принципе такие инструменты есть в любом браузере, а если учесть, что большая часть браузеров работает на одном движке, что и Chrome, то тут в принципе не будет особых различий. Также еще очень хорош Firefox со своим инструментом Firebug.

Общий вид панели Sources

Запустите браузер Chrome.

Нажмите F12, при этом запустятся Инструменты разработчика.

Перейдите на вкладку Source


Здесь можно выделить 3 зоны:

  • Область исходных файлов. В ней находятся все файлы проекта
  • Область текста. В этой области находятся текст файла
  • Область информации и контроля. О ней разговор пойдет позже
  • Как правило при отладке область исходных файлов не нужна, поэтому ее можно скрыть кнопкой.

    Общие кнопки управления

    3 наиболее часто используемые кнопки управления:

    Формат Эта кнопка позволяет отформатировать код. Может вам понадобиться, если вы желаете отформатировать чужой код. Консоль Очень важная кнопка по нажатию на которой открывается консоль. В консоли можно вводить различные команды и операторы на JavaScript. Окно В случае с большим участком кода позволяет открыть код в отдельном окне. Точки останова

    Рассмотрим на примере файла pow.js. Если клацнуть на любой строке этого файла, то на этой строке будет задана точка останова.

    Выглядеть это примерно так:


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

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

    Информация о точке останова появляется на вкладке Breakpoints.

    Вкладка Breakpoints очень полезна, когда код очень большой, она позволяет:

    • Быстро перейти на то место кода, где поставлен брейкпойнт простым кликом на текст.
    • Временно отключить точку останова кликом на чекбокс.
    • Быстро удалить точку останова правым кликом на текст и выбором Remove.

    Некоторые дополнительные возможности

    • Точку останова можно инициировать и напрямую из а скрипта, командой debugger: function pow(x, n) { ... debugger; // 300) { debugger; // запускаем отладчик и прерываем выполнение кода }

      Другие способы прервать выполнение кода

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

      Остановка при изменении DOM

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

      На панели кода HTML при нажатии правой кнопки мыши на нужном элементе можно выбрать условия остановки кода (изменение атрибутов, добавление/удаление потомков, удаление элемента) при изменении DOM. Перегрузите код и при изменении элементов выполнение кода остановится.

      Остановка при появлении всех или необрабатываемых исключений

      Большинство инструментов разработчика позволяют останавливать выполнение скрипта при появлении исключений. В Chrome данный функционал может быть включен с помощью иконки "Pause " в нижней строке интерфейса.

      Можно выбрать, для каких исключений будет выполняться остановка выполнения кода. Пример, приведенный ниже, демонстрирует одно необрабатываемое и одно обрабатываемое (блок try|catch) исключения:

      Var t = 3, p = 1; function calcPhotos(total_photos, prev_total_photos) { var total_photos_diff = total_photos - prev_total_photos; // Первая группа console.info("Total difference is now " + total_photos_diff); // Обновляем значения t = t+5; p = p+1; // Необрабатываемое исключение if (total_photos_diff > 300) { throw 0; } // Обрабатываемое исключение if (total_photos_diff > 200) { try { $$("#nonexistent-element").hide(); } catch(e) { console.error(e); } } } setInterval(function() { calcPhotos(t,p); },50);

      Введение в стек вызовов

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

      Когда выполнение скрипта прерывается, обратите внимание на правую панель, на которой представлена полезная информация, среди которой содержится стек вызовов (Call stack).

      Стек вызовов показывает полный путь, который привел к точке появления ошибки и остановки выполнения кода.

      На представленном ниже рисунке ошибка намеренно сгенерирована в функции incrementValues() , что привело к остановке выполнения кода. инструмент разработчика показывает полный стек вызовов, что позволяет определить потенциально опасные места.

      Заключение

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

      Представьте себе, что вы работаете над этим невероятным новым веб-приложением, и ваши тестеры попросили вас исправить следующие ошибки:

    • “Loading…” сообщение строки состояния не исчезает, когда приложение закончило загружаться.
    • Язык по умолчанию - норвежский, даже в английских версиях IE и Firefox.
    • Где то в коде образовалась глобальная переменная prop (зло - прим. пер.).
    • В DOM-вьювере все элементы почему то имеют атрибут «clone».
    • Запуск отладчиков
      • В Firefox вы должны убедится, что у вам установлено расширение Firebug. Выберите “Инструменты > Firebug > Open Firebug”.
      • В Опере 9.5+, выберите “Инструменты > Дополнительно > Средства разработки.”
      • В бете IE, выберите “Сервис > Панели > Панели обозревателя > IE Developer Toolbar.”
      • В Safari или WebKit, сначала включите меню отладки (1) , затем выберите “Разработать > Показать веб-инспектор”
      Пришло время запускать отладчики. Так как некоторые инструкции требуют изменения кода, вам лучше сохранить тестовую страницу и загрузить ее браузером с диска.Ошибка № 1: Сообщение “Загрузка …” Если вы посмотрите на отлаживаемое приложение, то сначала вы увидите то, что изображено на рисунке 1.


      рис. 1: начальный вид нашего JavaScript-приложения в Dragonfly и Firebug, соответственно.

      Когда вы смотрите на исходный текст в отладчике, обратите внимание на функцию clearLoadingMessage() в самом начале кода. Это неплохое место для контрольной точки.

      Как её поставить:

    • Щелкните мышью в левом поле на номере строки, чтобы установить контрольную точку на первой строке
    • Перезагрузите страницу.
    • Обратите внимание: контрольная точка должна быть установлена на строке с кодом, который выполнится, когда функция будет запущена. Строка, которая содержит clearLoadingMessage(){ не подходит, так как является лишь определением функции. Если вы установите контрольную точку здесь, отладчик на ней не остановится, вместо этого контрольную точку надо устанавливать внутри функции.

      Когда страница будет перезагружена, выполнение скрипта будет остановлено и вы увидите то, что показано на рисунке два.


      рис. 2: отладчики остановились в контрольной точке внутри clearLoadingMessage.

      Давайте взглянем на код функции. Как нетрудно заметить, в ней обновляются два DOM элемента, а в строке 31 упоминается слово statusbar. Похоже, что getElements("p", {"class":"statusbar"}).innerHTML ищет элемент statusbar в дереве DOM. Как бы нам быстро проверить своё предположение?

      Вставьте эту инструкцию в командную строку, чтобы проверить. На рисунке три показаны три скриншота (Dragonfly, Firebug и IE8) после чтения innerHTML или outerHTML элемента, возвращенного командой, которую вы исследуете.

      Чтобы проверить сделайте следующее:

    • Найдите командную строку:
      * В Firebug, переключитесь в закладку “Console”.
      * В Dragonfly, просмотрите пониже панели кода JavaScript.
      * В IE8, найдите закладку справа «Console».
    • Вставьте getElements("p", {"class":"statusbar"}).innerHTML в командную строку.
    • Нажмите Enter.



    • рис. 3: вывод результата команды в Dragonfly, Firebug, и IE8, соответственно.

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

      Можно использовать консоль, чтобы провести более глубокое исследование. Строка JavaScript, которую мы изучаем, делает следующие три вещи:

    • Получает ссылку на элемент statusbar.
    • Находит firstChild, другими словами, первый узел в этом параграфе.
    • Устанавливает свойство innerText.
    • Давайте попробуем запустить в консоли, что-то большее, чем предыдущая команда. Например вы можете попробовать узнать, какое текущее значение у свойства innerText, перед тем как ему присваивается новое значние. Чтобы узнать это, вы можете напечатать всю команду до знака "=" в командную строку: getElements("p" , {"class" :"statusbar" }).firstChild.innerText

      Сюрприз, на выходе… ничего. Таким образом выражение getElements ("p", {"класс:"statusbar" "}) .firstChild указывает на какой то объекст в DOM, который не содержит никакого текста, или не имеет свойства innerText.

      Тогда, следующий вопрос: что на самом деле является первым дочерним элементом у параграфа? Давайте зададим этот вопрос коммандной строке. (См. четвертый рисунок).

      рис. 4: командная строка отладчика СтDragonfly, вывод [объект Text].

      Вывод отладчика Dragonfly’s - [объект Text] показывает, что это - текстовый узел DOM. Таким образом мы нашли причину первой проблемы. У текстового узла нет свойства innerText, следовательно, установка значения для p.firstChild.innerText ничего не делает. Эта ошибка легко может быть исправлена, если заменить innerText на nodeValue, который является свойством, определенным стандартом W3C для текстовых узлов.

      Теперь, после того как мы разобрались с первой ошибкой:

    • Нажмите или кнопку Run, чтобы закончить скрипт.
    • Не забудьте сбросить поставленную контрольную точку, кликнув по номеру строки еще раз.
    • Ошибка два: проблема определения языка. Вы, возможно, обратили внимание на переменную lang;/*language*/ в начале скрипта. Можно предпложить, что код устанавливающий значение этой переменной и вызывает проблему. Можно попробовать найти этот код используя встроенную в отладчики функцию поиска. В Dragonfly поиск находтится прямо над просмотрщиком кода, в Firebug - в правом верхнем углу (см. рисунок 5)

      Чтобы найти место, где вероятно происходит проблема локализации сделайте следующее:

    • Напечатайте lang = в поле поиска.
    • Установите контрольную точку на строке, где переменной lang задается значение.
    • Перезагрузите страницу.
    • У WebInspector тоже есть очень удобная функция поиска. Она позволяет искать что угодно одновременно и в разметке страницы, и в CSS, и в коде JavaScript. Результаты показывюется на отдельной панели, где вы можете дважды кликнуть по ним, чтобы перейти в нужное место, как показано на скриншоте.


      рис. 5: поиск в Dragonfly и в WebInspector.

      Для того, чтобы проверить, что делает эта функция:

    • Нажмите кнопку «step into» для входа внутрь функции getLanguage.
    • Жмите ее еще и еще, пошагово выполняя код
    • В окне просмотра переменных смотрите как меняются их значния.
    • Войдя в функцию вы увидите попытку прочитать язык из строки юзер-агента браузера, путем анализа navigator.userAgent.
      var str1 = navigator.userAgent.match(/\((.*)\)/);
      var ar1 = str1.split(/\s*;\s*/), lang;
      for (var i = 0; i < ar1.length; i++){
      if (ar1[i].match(/^(.{2})$/)){
      lang = ar1[i];
      }
      }

      В процессе пошагового прохождения кода, вы можете использовать окно просмотра локальных переменных. На рисунке 6 показано как это выглядит в Firebug и IE8 DT, массив ar1 мы развернули, чтобы видеть его элементы.

      рис. 6: Панель просмотра локальных переменных фукции getLanguage в Firebug IE8’s

      Выражение ar1[i].match(/^(.{2})$/) просто ищет строку, состоящую их двух символов, типа «no», «en». Однако как видно на скриншоте у Firefox информация о языке представлена в виде «nn-NO» (2) . IE же и вовсе не помещает в юзер-агента информации о языке.

      Таким образом мы нашли вторую ошибку: определение языка производилось путем поиска двухбуквенного кода в строке юзерагента, но Firefox имеет пятисимвольное обозначение языка, а IE не имеет его вовсе. Такой код должен быть переписан и заменен на определение языка либо на стороне сервера с помощью HTTP заголовка Accept-Language, либо получением его из navigator.language (navigator.userLanguage для IE). Вот пример того, какой может быть такая функция

      function getLanguage() {
      var lang;

      if (navigator.language) {
      lang = navigator.language;
      } else if (navigator.userLanguage) {
      lang = navigator.userLanguage;
      }

      if (lang && lang.length > 2) {
      lang = lang.substring(0, 2);
      }

      return lang;
      }


      Ошибка три: таинственная переменная «prop»
      рис. 7: В панели просмотра переменных Firebug и Dragonfly видна глобальная переменная prop

      На рисунке 7 хорошо видно переменную «prop». В хорошо написанных приложениях количество глобальных переменных должно быть минимально, поскольку они могут стать причиной проблем, когда, например две части приложения захотят использовать одну и ту же переменную. Предположим, что завтра другая команда добавит новые возможности в наше приложение и тоже объявит переменную «prop». Мы получим две разные части кода приложения, использующие одно имя для разных вещей. Такая ситуация часто приводит к конфликтам и ошибкам. Можно попробовать найти эту переменную и объявить ее локальной. Для этого можно воспользоваться поиском, как мы делали это в предыдущем случае, но есть и более умный способ…

      У отладчиков для многих других языков программирования есть понятие «наблюдателя»(watch), который переходит в режим отладки, когда изменяется заданная переменная. Ни Firebug, ни Dragonfly не поддерживают «наблюдателей» в настоящее время, но мы можем легко эмулировать похожее поведение, добавив следующую строку в начало исследуемого кода:

      __defineSetter__("prop" , function () { debugger; });

      Сделайте следующее:
    • Добавьте отладочный код в начало самого первого скрипта.
    • Перезагрузите страницу.
    • Отметьте, как прерывается выполнение скрипта.
    • В IE8 DT имеется закладка «Watch», однако прерывания в момент изменения переменной не происходит. Так что этот пример работает только в Firefox, Opera и Safari.

      Когда вы перезагрузите страницу, выполнение кода немедленно остановится там где будет определена переменная «prop». Фактически остановка произодет в том месте, где вы добаили вышеупомянутую строку. Один клик по кнопке «step out» перекинет вас в место установки переменной.

      for (prop in attributes) {
      if (el.getAttribute(prop) != attributes) includeThisElement = false ;


      Нетрудно заметить цикл for в котором объявляется переменная prop без ключевого слова var, т.е. глобальная. Исправить это несложно, просто допишем var и исправим ошибку.Ошибка четыре: атрибут «clone», которого быть не должно Четвертая ошибка очевидно была обнаружена продвинутым тестировщиком, использующим DOM инспектор, так как ее существование никак не проявляется в пользовательском интерфейсе приложения. Если и мы откроем DOM инспектор (в Firebug это закладка «HTML», в Dragonfly она называется «DOM»), то увидим что многие элементы имеют атрибут clone, которого быть не должно.

      рис. 8: Dragonfly’s DOM инспектор показывает проблемный код.

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

      Самый быстрый способ найти эту проблему состоит в том, чтобы установить контрольную точку, которая срабатывает тогда, когда атрибут с названием clone будет установлен для какого-нибудь HTML элемента. Могут ли отладчики сделать это?

      JavaScript - очень гибкий язык, и одна из его сильных сторон (или слабых, в зависимости от вашей точки зрения) - это то, что вы можете заменить базовые функции языка своими собственными. Добавьте этот кусок кода на страницу, он переопределит системный метод setAttribute, вызывая остановку кода в момент установки свойства «clone»:

      var funcSetAttr = Element.prototype.setAttribute; /* сохраняем ссылку на системный метод */
      Element.prototype.setAttribute = function (name, value) {
      if (name == "clone" ) {
      debugger; /* останавливаем скрипт */
      }
      funcSetAttr.call(this ,name,value); /* вызываем ранее сохраненный системный метод, чтобы нормальные свойства устанавливались корректно */
      };

      Итак, делаем следующее:
    • Добавьте приведенный код в начало первого скрипта на странице.
    • Перезагрузите страницу.
    • После перезагрузки, скрипт начинает обрабатывать DOM-дерево, но сразу же останавливается, как только произойдет установка «плохого» атрибута. (Обратите внимание, что в текущих версиях Firefox, реализация setAttribute различна для разных элементов. Код, приведенный выше работает всегда как надо только в Опере; чтобы получить тот же самый эффект в Firefox, вы можете заменить слово Element на HTMLFormElement, чтобы переопределить более специфический метод HTMLFormElement.prototype.setAttribute).

      Когда выполнение остановится в контрольной точке, вы захотите узнать где же произошел вызов setAttribute(), то есть вам нужно вернуться на уровень выше в цепочке вызовов функций и посмотреть что происходит там. Для этого вы можете использовать стек вызовов.


      рис. 9: Стек вызовов в Dragonfly и IE8.

      На рисунке 10 показан стек в Firebug. В строке "setAttribute

    Есть вопросы?

    Сообщить об опечатке

    Текст, который будет отправлен нашим редакторам: