


Для подготовки к собеседованию Frontend мало узнавать термины JavaScript и CSS. Нужно объяснять, что произойдёт в браузере, а затем проверять своё объяснение на небольшом интерфейсе. Ниже разберём вопросы с ответами и две задачи: порядок асинхронных операций и список с удалением элементов.
Это учебный практикум Mentoring.digital для начинающего фронтенд-разработчика. Он не является списком вопросов конкретного работодателя. Если в вакансии нужен React или TypeScript, после этой базы отдельно подготовьте примеры по указанному стеку.
Кнопка уже имеет семантику действия, получает фокус и поддерживает активацию с клавиатуры. У обычного div это поведение пришлось бы создавать вручную. Для перехода на другой адрес нужна ссылка. В форме у кнопки явно укажите type="button", если она не должна отправлять форму. На интервью полезно назвать не только тег, но и проверить Tab, Enter и Space.
При box-sizing: content-box заданная ширина относится к содержимому: padding и border добавятся снаружи. При border-box они входят в заданную ширину. Margin остаётся внешним в обоих случаях. Например, содержимое шириной 300 px с отступами по 20 px и рамкой по 1 px занимает 342 px без учёта margin.
Сжатие элемента ограничивается его минимальным размером. Для текстовой части часто нужно явно разрешить сжатие через min-width: 0, а для непрерывного текста определить перенос, например overflow-wrap: anywhere. Эти свойства решают разные части задачи. Не скрывайте проблему общим overflow: hidden на странице: так можно обрезать кнопку или фокус.
target указывает на объект, которому исходно адресовано событие. В нашем обычном DOM это может быть span внутри кнопки. currentTarget во время работы обработчика указывает на элемент, на котором обработчик установлен. Если слушатель находится на ul, проверка event.target.tagName === 'BUTTON' пропустит клик по вложенному span. Для поиска кнопки пригодится closest.
Один обработчик на предке может обслуживать подходящие дочерние элементы благодаря распространению события. Это удобно для динамического списка. Но нужно проверить целевой элемент, границы контейнера и вид события. Не все события всплывают, а остановка распространения в другом обработчике может изменить поведение.
Полученный HTTP-ответ с ошибочным статусом сам по себе не отклоняет promise fetch. Сначала проверьте response.ok или конкретный статус, затем разбирайте тело. Сетевая ошибка и ошибка JSON требуют отдельного понимания. Не показывайте пользователю «всё успешно» только потому, что удалось получить объект Response.
async function loadItems(url) {
const response = await fetch(url);
if (!response.ok) {
throw new Error(`HTTP ${response.status}`);
}
return response.json();
}
Этот фрагмент показывает проверку статуса, а не готовый сетевой слой. Для реального интерфейса дополнительно нужны состояния загрузки, ошибки и пустого результата, а при смене запроса стоит продумать отмену или защиту от устаревшего ответа.
Запустите фрагмент как отдельный скрипт. До запуска запишите ожидаемую последовательность:
console.log('A');
setTimeout(() => console.log('B'), 0);
Promise.resolve().then(() => console.log('C'));
console.log('D');
Ответ: A, D, C, B. Синхронные строки выполняются первыми. Обработчик уже выполненного promise попадает в очередь микрозадач и выполняется после завершения текущего кода. Callback таймера относится к следующей задаче. Значение 0 у setTimeout не означает немедленное выполнение и не задаёт точное время вызова.
Усложните упражнение: добавьте второй then и объясните его положение в очереди. Не переносите вывод о таймере на любые асинхронные операции: важны момент постановки задачи и среда выполнения.
Условие. В списке две задачи. Нажатие на текст внутри кнопки удаляет только соответствующую строку. Нажатие на название задачи ничего не удаляет. Счётчик обновляется, а длинное название переносится без горизонтальной прокрутки страницы. Сохраните код в новый учебный файл index.html и откройте его в браузере.
<!doctype html>
<html lang="ru">
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Учебный список</title>
<style>
* { box-sizing: border-box; }
body { max-width: 600px; margin: 24px auto; padding: 16px; }
li { display: flex; gap: 12px; margin: 12px 0; }
.label { min-width: 0; overflow-wrap: anywhere; flex: 1; }
button { flex-shrink: 0; }
</style>
<ul id="tasks">
<li><span class="label">Разобрать события DOM</span>
<button type="button" data-remove><span>Удалить</span></button></li>
<li><span class="label">Проверить длинное название задачи</span>
<button type="button" data-remove><span>Удалить</span></button></li>
</ul>
<p id="status" role="status">Задач: 2</p>
<script>
const list = document.querySelector('#tasks');
const status = document.querySelector('#status');
list.addEventListener('click', (event) => {
if (!(event.target instanceof Element)) return;
const button = event.target.closest('button[data-remove]');
if (!button || !list.contains(button)) return;
button.closest('li').remove();
status.textContent = `Задач: ${list.children.length}`;
});
</script>
</html>
Проверка instanceof Element позволяет безопасно вызвать closest. Поиск кнопки решает случай с вложенным span. Проверка contains не даёт обработчику принять кнопку вне списка. Удаление выполняется после этих условий, а счётчик вычисляется по оставшимся дочерним строкам.
| Действие | Что должно получиться |
|---|---|
| Клик по названию | Обе строки остаются |
| Клик по span «Удалить» | Удаляется одна строка, счётчик равен 1 |
| Удаление второй строки | Пустой список, счётчик равен 0 |
| Активация кнопки клавиатурой | То же действие, что при клике |
| Длинное название и узкое окно | Текст переносится, кнопка доступна |
Учебное решение не сохраняет задачи после перезагрузки и не управляет фокусом после удаления. Для рабочего интерфейса это отдельные требования: например, переводить фокус на следующую доступную кнопку или заголовок пустого списка. Умение назвать такие ограничения на собеседовании полезнее, чем объявить короткий пример завершённым продуктом.
Если порядок вывода оказался неожиданным, повторите очереди задач и микрозадач. Если клик по тексту работает иначе, чем по краю кнопки, разберите target и делегирование. Если карточка расширяет экран, отдельно исследуйте минимальную ширину flex-элемента. Так план строится по наблюдаемой ошибке.
На курсах frontend с индивидуальной практикой можно согласовать упражнения по нужному стеку. Для пробного интервью выберите наставника по фронтенд-разработке и принесите свои решения, список проверок и вопросы, на которые пока трудно ответить вслух.