Кнопка может не работать по разным причинам: браузер не загрузил скрипт, скрипт не нашёл элемент или условие по ошибке запрещает действие. Разберём три версии кликера с разными ошибками, а затем ты найдёшь и исправишь ещё одну самостоятельно.
Нужен final/ урока о параметрах и return. start/ здесь — его точная копия. Это рабочая версия: с ней можно сравнивать поведение сломанных копий.
Выбирай стартовую версию, промежуточный этап или финал в просмотрщике. Во вкладке «Инструкция» — как запустить проект и чем отличаются версии. Решения самостоятельных заданий открывай после своей попытки.
Скачать ZIPРаспакуй архив целиком. У каждой версии своя папка с index.html, style.css и game.js. Открывай HTML внутри выбранной папки двойным щелчком; после правки сохраняй файл и обновляй браузер. Установка Node.js, аккаунт и сервер здесь не нужны. CSS уже знаком по первому модулю и дан как готовое оформление.
Важно о версиях: broken-path/, broken-selector/, broken-rule/ и exercise/ специально содержат ошибки. Их не нужно брать за старт следующего урока. Каждая папка независима, открывай только её собственный index.html.
Как искать ошибку по шагам
Сначала опиши, что сделал и что увидел. Затем назови одну возможную причину. Проверь её через сообщение или значения и только потом меняй код. Одновременная замена пяти строк мешает понять, что помогло. После исправления повтори тот же сценарий и похожий случай с другими значениями.
Открой DevTools через F12 или меню браузера, выбери Console. Сохрани файл и обнови страницу, чтобы увидеть ошибку нового запуска. Читай первое относящееся к твоему game.js сообщение, а не случайные сообщения расширений. Справа от сообщения обычно есть ссылка на файл и строку. Нажми её: редактор Sources покажет место, где выполнение остановилось с ошибкой. Это место обнаружения проблемы, а её причина может находиться раньше.
Случай 1: не загрузился скрипт
Открой broken-path/index.html. Нажми сбор: цифры стоят на месте. Открой Console и обнови страницу. Сообщение об ошибке загрузки будет ссылаться на games.js; точный текст зависит от браузера и запуска через файл или HTTP.
Запиши гипотезу: «браузер ищет несуществующее имя». Сравни строку script в HTML с именем файла в папке. В папке game.js, а подключено games.js. Исправь только имя в src, сохрани HTML и обнови страницу. Клик должен дать 1/9. Если имя совпало, проверь, что файл не называется game.js.txt.
Дополнительная проверка: вкладка Network после обновления показывает запросы ресурсов. При HTTP для отсутствующего файла обычно виден 404; при открытии с диска браузер может показать другую ошибку загрузки. Не жди обязательно одного кода статуса — проверь адрес и факт загрузки. Позже разберём запуск через локальный HTTP-сервер подробнее.
Показать исправление
<script src="game.js" defer></script>В этом проекте файл называется game.js и лежит рядом с index.html. Это имя нужно указать и в src.
Случай 2: элемент не найден
Открой broken-selector/index.html. Здесь файл загружается, но Console сообщает ошибку чтения свойства addEventListener у null. null — специальное значение «объект не найден» в результате такого поиска, а не кнопка с пустым текстом.
Нажми ссылку на строку. Проблема проявилась при регистрации на gatherButton. Найди, где эта переменная получила значение. В Console выполни отдельно:
document.getElementById('gather-buton')
document.getElementById('gather-button')
Первое выражение вернёт null, второе — элемент кнопки. В слове button потеряна буква. Исправь только строку поиска в game.js и повтори старт и три сбора. Помни: getElementById получает имя без #. При правильном имени, но слишком раннем поиске тоже возможен null; наш defer обеспечивает нужный порядок.
Показать исправление
const gatherButton = document.getElementById('gather-button');Случай 3: Console молчит, а правило неверно
Открой broken-rule/index.html. Набери ровно 10 кристаллов: покупка почему-то недоступна. Ошибок выполнения нет, потому что JavaScript умеет выполнить записанную проверку. Неправильным оказалось само правило.
Сформулируй ожидаемое поведение до правки: 9 — нельзя, 10 — можно, 11 — можно. Проверь только функцию, не проходя игру каждый раз:
console.log(canBuyUpgrade(9, 10));
console.log(canBuyUpgrade(10, 10));
console.log(canBuyUpgrade(11, 10));
Ты получишь false, false, true. Значит, мы нашли причину: условие не включает равенство. Посмотри строку return и сравни > с >=. Измени один оператор и снова проверь все три случая, затем покупку в интерфейсе. Нельзя считать исправление проверенным только потому, что кнопка однажды сработала.
Показать исправление
function canBuyUpgrade(points, price) {
return points >= price;
}Останавливаемся на нужной строке
В исправленном проекте открой Sources, найди game.js, затем строку score = score + calculateReward(clickPower, 1); внутри handleGather. Нажми номер строки — появится точка останова, breakpoint. Вернись к игре и нажми сбор: браузер остановится перед выполнением этой строки.
Посмотри значения score, energy и clickPower в разделе Scope или введи их имена в Console, пока выполнение приостановлено. Кнопкой Step over выполни следующую инструкцию: score изменится, но render ещё не был вызван, поэтому экран может показывать старое число. Так видно, что число в переменной уже изменилось, а надпись на странице — ещё нет. Нажми Resume для продолжения. Сними breakpoint повторным нажатием на номер строки, иначе последующие клики будут снова останавливать игру.
Вместо breakpoint для короткой проверки допустимо поставить console.log(score, energy) перед и после действия, затем убрать диагностические строки. Лог показывает значения во время выполнения, но сам по себе не чинит правило.
Самостоятельно: отдых меняет не то
Открой exercise/index.html. Собери три кристалла и отдохни. Ожидается 3/10. Запиши фактические числа, одну гипотезу и проверку. Исправь причину, не заменяя game.js файлом final. Затем проверь отдых при полном запасе, после одного сбора и после трёх.
Подсказка 1
Сбор работал до отдыха, поэтому сначала изучи обработчик именно того действия, которое меняет не ту величину. Сравни данные до и после него.
Подсказка 2
Остановись внутри handleRest. Посмотри левую сторону присваивания: какое имя получает 10? Сравни это с формулировкой правила отдыха.
Разбор после попытки
В handleRest ошибочно присваивается score = 10. Нужно energy = 10. Render честно показывал ошибочное состояние; менять его было бы исправлением симптома. В твоей записи должны остаться наблюдение 10/7, гипотеза о неверной переменной, проверка и повторный результат 3/10.
Сохраняем рабочую версию
Папка final/ совпадает с рабочим итогом прошлого урока: 0 очков, 10 энергии, сила 1; покупка за 10 один раз, победа при 20, запрет действий после победы. С этой версии начнём следующий урок. Исправленные копии и записи о найденных ошибках сохрани отдельно: к ним можно вернуться, если встретишь похожую проблему.
Готово, когда: ты различаешь ошибку загрузки, ошибку выполнения и ошибку правила; находишь строку по Console; можешь проверить гипотезу значением или breakpoint и объяснить самостоятельную правку. Если пришлось подсмотреть исправление, закрой пример и попробуй найти ту же ошибку заново.
Разбор самостоятельного задания
Сначала попробуй решить задание сам. Затем сравни с примером ту функцию или условие, которые вызвали затруднение. Разбор самостоятельной задачи доступен во вкладке «Решение» в просмотрщике исходников.
Справочник: точки останова в Chrome DevTools. В других браузерах названия кнопок могут отличаться, но порядок проверки тот же.