Как найти код, меняющий фон при клике на кнопку

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

Теория и пошаговая диагностика

Изменение фона страницы при клике обычно происходит одним из двух путей:

  • (A) JavaScript напрямую меняет body.style.backgroundColor или атрибут style.
  • (B) JavaScript меняет класс/атрибут (например, class="theme-blue" или data-theme="blue"), а уже CSS по этому классу/атрибуту задает фон.

Ниже приведен практический алгоритм, который позволяет найти «виновника» даже при плохой читаемости кода.

Подтверждение: меняется ли именно `body`

  • Необходимо открыть DevTools и перейти во вкладку Elements (Inspector).
  • Необходимо выбрать узел <body> и наблюдать, что изменяется при клике: style, class, data-* атрибуты.
  • Если у body ничего не меняется, возможно, меняется другой контейнер (например, основной wrapper), либо создается наложение (overlay), которое визуально выглядит как изменение фона.

Практический прием: поставить DOM breakpoint на body, чтобы остановиться ровно на той строке JavaScript, которая меняет DOM/атрибут.

Elements (Inspector)
  └─ выбрать <body>;
      └─ Break on...
          ├─ Attribute modifications
          ├─ Subtree modifications
          └─ Node removal

Смысл:

  • Attribute modifications — остановка при изменении атрибутов (class, style, data-*).
  • Subtree modifications — остановка при изменении потомков (когда добавляются/удаляются/перестраиваются элементы внутри).
  • Node removal — остановка при удалении выбранного узла.

Поиск обработчика клика у кнопки

Чтобы понять, какой код реагирует на клик:

  • Необходимо выделить кнопку во вкладке Elements.
  • Необходимо открыть панель со слушателями событий (Event Listeners) и найти click.
  • Необходимо раскрыть обработчики и перейти к месту в исходниках, где они определены или где навешиваются.

Дополнительно полезно включить остановку на событиях:

  • В Sources (Debugger) обычно доступен раздел Event Listener Breakpoints, где можно включить паузу на Mouse -> click.
  • После включения паузы необходимо снова кликнуть по кнопке, отладчик остановится на коде, выполняемом в рамках обработки клика.

Сведение «эффект → причина» через Call Stack

После остановки выполнения в Debugger/Sources необходимо:

  • Посмотреть Call Stack (стек вызовов) и определить ближайшую к действию функцию.
  • Перейти к строке, где меняется состояние: style, classList, dataset, либо вызов функции, которая это делает.
  • Определить тип изменения и выбрать корректную правку.

Типичные «сигналы» в коде:

  • Прямая смена стиля: document.body.style.backgroundColor = 'blue'.
  • Подмена атрибута: document.body.setAttribute('style', ...).
  • Переключение класса: document.body.classList.add('is-blue').
  • Переключение темы: document.body.dataset.theme = 'blue'.

Упрощенная схема действий:

Клик по кнопке
   │
   ├─(A) Остановиться на event listener breakpoint (click)  → увидеть обработчик
   │
   └─(B) Остановиться на DOM breakpoint (body attribute modified)
         → увидеть строку кода, которая меняет class/style
                 │
                 ├─ Меняется body.style / атрибут style → причина в JS
                 └─ Меняется class/data-атрибут         → причина в связке JS + CSS
Два наиболее сильных механизма в DevTools для таких задач — DOM breakpoints (остановка на коде, меняющем DOM) и event listener breakpoints (остановка на коде, выполняющемся после конкретного события, например click).

Проверка CSS-стороны (если меняется класс/тема)

Если выяснилось, что меняется class или data-theme, значит фон рисуется CSS-правилами. Тогда необходимо:

  • В Elements открыть вкладку Styles/Computed для body (или для элемента, который реально окрашивает фон).
  • Найти правило, которое задает background-color.
  • Проверить специфичность и порядок правил, а также возможные темы, модификаторы, медиа-условия.

Практическая таблица «признак → трактовка → следующий шаг»:

НаблюдениеЧто это обычно означаетЧто делать дальше
У body появился style="background-color: ..."JavaScript напрямую установил стильНайти строку установки и заменить на корректную логику (класс/тема/переменные)
У body изменился class (например, theme-blue)JavaScript переключает состояние, CSS рисуетНайти место переключения класса и CSS-правило темы
Фон меняется, но body не менялсяМеняется контейнер, псевдоэлемент, или наложениеСтавить DOM breakpoint на подозрительный контейнер, искать изменение его классов/стилей
Слушатели у кнопки не видны, но клик влияетВероятно делегирование на document/windowВключить паузу на click, смотреть Call Stack и исходное место регистрации
Если на странице есть сторонние виджеты или минифицированные бандлы, один клик может запускать длинную цепочку вызовов. В такой ситуации основная цель — найти первую «осмысленную» функцию в Call Stack, которая меняет class/style/dataset, а не пытаться читать весь бандл целиком.

Как исправить ситуацию правильно

Цель исправления — не «перекрыть» фон, а сделать механизм изменения фона явным, предсказуемым и локализованным (один источник правды).

Рекомендуемые принципы исправления:

  • В CSS следует описывать темы через классы или CSS-переменные, а не через массовые !important.
  • В JavaScript следует переключать только состояние (класс/атрибут), а не «рисовать» стили напрямую на body, если в этом нет строгой необходимости.
  • Следует централизовать переключение темы: один обработчик, одна функция, одно место изменения состояния.

Пример: переключение через класс

<!-- HTML -->
<button id="toggle-theme">Toggle theme</button>
/* CSS */
body {
  background-color: red;
}

body.is-blue {
  background-color: blue;
}
// JS
document.getElementById('toggle-theme')?.addEventListener('click', () => {
  document.body.classList.toggle('is-blue');
});

Плюсы:

  • Логика темы отделена от рисования.
  • CSS остается единственным местом, где описаны цвета.

Пример: масштабируемо через CSS-переменные

/* CSS */
:root {
  --page-bg: red;
}

body {
  background-color: var(--page-bg);
}

body[data-theme="blue"] {
  --page-bg: blue;
}
// JS
document.getElementById('toggle-theme')?.addEventListener('click', () => {
  const next = document.body.dataset.theme === 'blue' ? 'red' : 'blue';
  document.body.dataset.theme = next;
});

Плюсы:

  • Удобно расширять на множество цветов и параметров (текст, границы, акценты).
  • Можно менять тему, не переписывая множество CSS-правил.
Если фон меняется из-за расширения браузера или внешней инъекции (например, через внедренный скрипт), то «исправление в коде сайта» не даст результата. Для проверки необходимо воспроизвести проблему в чистом профиле браузера и без расширений.

Итого: верным является вариант 3, потому что DevTools позволяют увидеть обработчики click у кнопки и остановиться на коде, который меняет body (DOM breakpoints) или выполняется после клика (event listener breakpoints); исправление следует делать через явную логику темы (класс/атрибут/CSS-переменные), а не через маскирующие !important.