DOM-тест: «Сленг»
Брифинг перед миссией: пять вопросов о современном сленге. Выберите ответ — блок увеличится, а через пару секунд варианты по очереди уедут вправо, и в поле вопроса появится маркер.
Вопросы закончились
Как устроен тест
Все вопросы хранятся в массиве объектов. У каждого вопроса есть текст и свой массив ответов, а у правильного ответа — флаг correct и пояснение. Перед началом массив вопросов перемешивается алгоритмом Фишера — Йетса, и так же перемешиваются ответы внутри каждого вопроса. Поэтому при каждом запуске порядок новый, а повторов не бывает: алгоритм только переставляет элементы местами и ничего не копирует.
На странице есть одна область для динамического добавления элементов. Скрипт создаёт в ней блок вопроса и ряд блоков с ответами через document.createElement, нумеруя вопросы по порядку вывода. Вопросы складываются в столбец, а ответы стоят горизонтально, как требует первый вариант задания. Пока выбранный ответ не обработан, ряд блокируется: второй раз нажать нельзя.
Всё движение выполняет CSS. Скрипт лишь добавляет классы: chosen слегка увеличивает нажатый блок, right расширяет верный ответ и раскрывает пояснение, leave отправляет блок вправо. Чтобы блоки уезжали по очереди, у каждого есть своя CSS-переменная --i, и задержка перехода считается как calc(var(--i) * 260ms). Рамка при наведении — это внутренняя тень box-shadow: её толщина меняется без сдвига вёрстки.
Когда вопросы заканчиваются, над областью появляется надпись «Вопросы закончились» и статистика: сколько ответов верных из общего числа. После этого вопросы становятся кнопками: нажатие раскрывает блок с правильным ответом, а у остальных вопросов он в это время скрыт. В пятом вопросе два верных варианта, поэтому засчитывается любой из них, а при просмотре показываются оба.
Статус-бар внизу страницы тоже следит за тестом: «Осталось» — сколько вопросов впереди, «Верно» — счёт, «Точность» — процент попаданий. Лицо морпеха ухмыляется после верного ответа и морщится после ошибки — как в DOOM, когда игрок подбирает оружие или получает урон.