Практика по JS
Структура практического задания: «Добавляем интерактивность в CV с JavaScript»
1. Введение (5-7 мин)
- Цель: Показать, как «оживить» статичное CV.
- Пример Codepen: Демо готового проекта (CV с темной темой, анимациями, динамическими секциями).
- Исходные данные участников:
- У всех есть CV на HTML/CSS (предложить универсальный шаблон для тех, у кого нет).
- Фокус на модификацию существующего кода, а не создание с нуля.
2. Базовое подключение JS (15 мин)
- Задача: Научиться связывать JS с HTML.
- Codepen-демо:
<!-- Добавляем в конец body --> <script> console.log("CV загружено!"); document.body.style.border = "2px solid green"; // Визуальный маркер </script> - Практика:
- Добавить тег
<script>в свой CV. - Проверить работу через
console.log(). - Изменить цвет заголовка через JS.
- Добавить тег
3. Переключатель тем (25 мин)
-
Логика:
- Создать кнопку в HTML.
- Написать функцию переключения классов.
- Добавить CSS-стили для темной темы.
-
Codepen-шаблон:
<button id="theme-toggle">🌓</button>.dark-theme { background: #333; color: white; }const toggleBtn = document.getElementById('theme-toggle'); toggleBtn.addEventListener('click', () => { document.body.classList.toggle('dark-theme'); // Сохранение темы в localStorage (бонус для продвинутых) }); -
Задание:
- Реализовать переключатель.
- Добавить плавный переход через CSS
transition.
4. Динамическое отображение навыков (20 мин)
- Идея: Генерация списка навыков из массива.
- Codepen-пример:
const skills = ['HTML', 'CSS', 'Git', 'Адаптивная верстка']; const skillsList = document.getElementById('skills'); skills.forEach(skill => { const li = document.createElement('li'); li.textContent = skill; skillsList.appendChild(li); }); - Задание:
- Заменить статичный список в CV на динамический.
- Добавить кнопку сортировки навыков.
5. Интерактивная секция «Опыт работы» (30 мин)
- Задача: Показать/скрыть описание по клику.
- Шаги:
- Добавить класс
.collapsedсmax-height: 0в CSS. - Написать функцию для переключения видимости.
- Добавить класс
- Codepen-фрагмент:
document.querySelectorAll('.experience-header').forEach(header => { header.addEventListener('click', () => { header.nextElementSibling.classList.toggle('collapsed'); }); }); - Дополнительно: Анимация через CSS
transition.
6. Валидация формы контактов (20 мин)
- Цель: Проверка email перед отправкой.
- Codepen-демо:
<form id="contact-form"> <input type="email" id="email"> <button type="submit">Отправить</button> </form>document.getElementById('contact-form').addEventListener('submit', (e) => { e.preventDefault(); const email = document.getElementById('email').value; if (!email.includes('@')) { alert('Некорректный email!'); return; } // Отправка данных... });
7. Дополнительные идеи (10 мин)
- Для самостоятельной работы:
- Таймер обратного отсчета до следующего карьерного цели.
- Drag-and-drop для перестановки секций.
- Анимация прогресс-бара навыков.
8. Итог и рефлексия (10 мин)
- Проверка: У всех должен быть рабочий Codepen с модифицированным CV.
- Советы:
- Как дебажить код через DevTools.
- Где искать ошибки (Console > Errors).
Раздел 1. Введение
Основная цель:
Научиться добавлять интерактивность в статичный сайт (CV) с помощью JavaScript, превратив его в динамичное портфолио.
Что узнают участники:
- Как связывать JavaScript с HTML/CSS.
- Как создавать интерактивные элементы (переключатель темы, динамические списки, анимации).
- Как работать с событиями (клики, отправка форм).
- Как дебажить код и тестировать изменения в реальном времени.
Результат:
У каждого участника будет CV с рабочими JS-элементами, которые можно добавить в портфолио.
Пример готового проекта
Codepen-демо:
Ссылка на пример CV
Что включено в демо:
- Переключатель светлой/темной темы.
- Динамически генерируемый список навыков.
- Секции опыта работы с раскрывающимся описанием.
- Валидация формы контактов.
Важно:
- Участники будут модифицировать свой проект, а не создавать его с нуля.
- Если у кого-то нет готового CV, можно использовать универсальный шаблон (см. раздел 1.3).
Исходные материалы
Для участников:
-
Базовый CV на HTML/CSS.
-
Если своего нет, используйте шаблон:
<header> <h1>Иван Иванов</h1> <p>Начинающий веб-разработчик</p> </header> <section id="skills"> <h2>Навыки</h2> <ul class="skills-list"> <!-- Список будет заполнен через JS --> <li>HTML</li> <li>CSS</li> </ul> </section> <section class="experience"> <h2>Опыт работы</h2> <div class="experience-item"> <h3 class="experience-header">Стажер в IT-компании</h3> <p class="experience-description"> Участие в разработке фронтенда для внутренних проектов. </p> </div> </section> <section> <h2>Связаться со мной</h2> <form id="contact-form"> <input type="email" id="email" placeholder="Ваш email"> <button type="submit">Отправить</button> </form> </section> <!-- Кнопка переключателя темы (пока не работает) --> <button id="theme-toggle" style="position: fixed; top: 20px; right: 20px;">🌓</button> <!-- JS будет добавлен позже --> <script></script>
-
-
Требования к проекту:
- Все секции должны быть сверстаны (можно без сложного дизайна).
- Подключенные шрифты и стили (если есть).
Технические требования:
- Браузер с DevTools (Chrome, Firefox).
- Аккаунт на Codepen.io для сохранения работы.
Ключевые концепции JavaScript, которые будут использоваться
-
DOM-манипуляции:
- Изменение классов, стилей и содержимого элементов.
- Пример:
document.querySelector(),classList.toggle().
-
Работа с событиями:
- Обработка кликов, отправки форм.
- Пример:
addEventListener('click', callback).
-
Динамическое создание элементов:
- Генерация HTML из массивов данных.
- Пример:
document.createElement(),appendChild().
Почему это полезно?
- Для портфолио: CV с интерактивными элементами выделит вас среди других начинающих разработчиков.
- Для практики: Все примеры приближены к реальным задачам (например, темы оформления есть у большинства сайтов).
- Для развития: Вы сможете добавить в CV больше фич (анимации, API, слайдеры).
План
Пошагово внедрим в CV:
- Подключение JavaScript.
- Переключатель темы.
- Динамический список навыков.
- Интерактивные секции опыта.
- Валидация формы.
Перед началом работы
Проверьте, что у вас есть:
- Готовый CV на HTML/CSS или универсальный шаблон.
- Открыт Codepen для редактирования.
- Включена консоль браузера (F12 > Console).
Раздел 2. Базовое подключение JavaScript
Цель раздела: Научить участников подключать JavaScript к HTML, работать с консолью браузера и выполнять простые манипуляции с DOM.
Теория: Как работает JS в браузере
Ключевые концепции:
- Тег
<script>— элемент для вставки JS-кода.- Размещается в конце
<body>(для быстрой загрузки контента). - В Codepen можно использовать отдельную JS-панель.
- Размещается в конце
- DOM (Document Object Model) — представление HTML-документа в виде дерева объектов.
- Консоль разработчика — инструмент для отладки (открыть:
F12→ Console).
Пошаговая инструкция
Шаг 1: Добавление тега <script>
|
Шаг 2: Проверка подключения
|
Шаг 3: Простая манипуляция с DOM
|
Codepen-пример
Шаблон для практики
Исходный код:
|
|
Практическое задание
Задача: Добавить интерактивность в своё CV.
-
Изменение цвета заголовка:
const nameTitle = document.querySelector("h1"); nameTitle.style.color = "#3498db"; // Синий цвет -
Динамическое сообщение в консоль:
console.log("Текущая дата:", new Date().toLocaleDateString()); -
Добавление границы секциям:
document.querySelectorAll("section").forEach(section => { section.style.border = "1px solid #eee"; });
Частые ошибки
| Ошибка | Решение |
|---|---|
Uncaught TypeError: Cannot read properties of null |
Убедитесь, что элемент существует в HTML. |
| Скрипт не работает | Проверьте, что <script> расположен после элементов, которыми управляет. |
| Изменения не отображаются | Обновите страницу (Ctrl + F5). |
Советы по отладке
- Всегда проверяйте консоль на ошибки (
F12→ Console). - Используйте
console.log()для вывода промежуточных результатов. - Тестируйте код по частям, а не весь сразу.
Дополнительные задания
Для продвинутых:
- Добавьте анимацию при клике на кнопку:
button.addEventListener("click", () => { button.style.transform = "scale(0.95)"; setTimeout(() => { button.style.transform = "scale(1)"; }, 100); });
Что проверять после раздела
- Сообщение в консоли без ошибок.
- Визуальные изменения на странице (цвет заголовка, фон).
- Рабочая кнопка в Codepen-примере.
Раздел 3. Переключатель тем (Светлая/Темная)
Цель раздела: Реализовать динамическое переключение тем на сайте, сохраняя выбор пользователя.
Теория: Как работает переключение тем
Ключевые концепции:
- CSS-классы — переключаем стили через добавление/удаление классов.
- localStorage — сохраняем выбор темы между сессиями.
- События — обрабатываем клики на кнопке.
Почему именно так?
- Изменение классов эффективнее прямого изменения стилей через JS.
- localStorage позволяет запоминать выбор пользователя.
Пошаговая инструкция
Шаг 1: Добавить кнопку в HTML
|
Шаг 2: Стили для темной темы
|
Шаг 3: JavaScript-логика
|
Codepen-пример
Особенности реализации:
- Кнопка с иконкой луны/солнца (можно заменить на текст).
- Сохранение темы при перезагрузке страницы.
- Плавные переходы между темами.
Практическое задание
Задача: Интегрировать переключатель в своё CV.
-
Базовый вариант:
- Реализовать переключение фона body.
- Добавить консоль-лог при клике:
console.log('Текущая тема:', body.classList.contains('dark-theme') ? 'темная' : 'светлая');
-
Продвинутый вариант:
- Изменить иконку кнопки в зависимости от темы.
themeToggle.textContent = body.classList.contains('dark-theme') ? '☀️' : '🌙'; - Добавить кастомные свойства CSS (CSS Variables):
:root { --primary-bg: #f9f9f9; --text-color: #333; } .dark-theme { --primary-bg: #2c3e50; --text-color: white; } body { background: var(--primary-bg); color: var(--text-color); }
- Изменить иконку кнопки в зависимости от темы.
Частые ошибки
| Ошибка | Решение |
|---|---|
| Класс добавляется, но стили не меняются | Проверьте !important в CSS или специфичность селекторов. |
| Тема не сохраняется | Убедитесь, что localStorage работает (включите cookies в браузере). |
| Иконка не обновляется | Добавьте логику изменения иконки внутри обработчика клика. |
Советы по отладке
- Проверяйте классы через Инструменты разработчика (F12 → Elements).
- Используйте
localStorage.clear()для сброса темы. - Тестируйте на реальных проектах — некоторые стили могут конфликтовать.
Дополнительные идеи
- Системная тема по умолчанию:
// Автоопределение темы ОС const isDarkMode = window.matchMedia('(prefers-color-scheme: dark)').matches; if (isDarkMode) body.classList.add('dark-theme'); - Градиентные переходы — анимируйте изменение цвета фона.
Что проверять после раздела
- Кнопка меняет тему при клике.
- Тема сохраняется после перезагрузки.
- Нет конфликтов стилей в секциях CV.
Раздел 4. Динамическое отображение навыков
Цель раздела: Научить генерировать HTML-элементы из массива данных, работать с методами массива и DOM.
Теория: Зачем это нужно?
- Динамический контент — позволяет обновлять данные без правки HTML (например, список навыков из базы данных).
- Методы работы:
document.createElement()— создание элементов.appendChild()/innerHTML— добавление в DOM.forEach()— итерация по массиву.
Пошаговая инструкция
Шаг 1: Подготовка HTML
|
Шаг 2: Создание массива данных
|
Шаг 3: Генерация элементов
|
Codepen-пример
Особенности:
- Кнопка «Добавить навык» для интерактивности.
- Сортировка навыков по алфавиту.
|
Практическое задание
Задача: Реализовать динамический список в своём CV.
-
Базовый вариант:
- Заменить статичные навыки на массив.
- Добавить минимум 8 элементов.
-
Продвинутый вариант:
- Реализовать фильтрацию навыков по ключевому слову:
const filteredSkills = skills.filter(skill => skill.includes('CSS'));- Добавить кнопку «Сортировать А-Я»/«Сортировать Я-А»:
let isSortedAsc = true; document.getElementById('sort-button').addEventListener('click', () => { skills.sort((a, b) => isSortedAsc ? b.localeCompare(a) : a.localeCompare(b)); isSortedAsc = !isSortedAsc; updateSkillsList(); });
Частые ошибки
| Ошибка | Решение |
|---|---|
Cannot read property 'appendChild' of null |
Убедитесь, что элемент .skills-list существует в HTML. |
| Дублирование элементов при обновлении | Всегда очищайте контейнер (innerHTML = '') перед перерисовкой. |
| Кириллица сортируется некорректно | Используйте localeCompare(): skills.sort((a, b) => a.localeCompare(b)). |
Советы по отладке
- Проверяйте массив через
console.log(skills)перед рендерингом. - Используйте
debugger;для остановки выполнения кода в нужном месте. - Для сложных списков используйте библиотеки типа Vue.js (но это уже для продвинутых).
Дополнительные идеи
- Прогресс-бар навыков — визуализируйте уровень владения:
const skillsWithLevel = [ { name: 'HTML', level: 90 }, { name: 'CSS', level: 85 } ]; // Генерируем div с width = level + '%' - Drag-and-Drop — разрешите менять порядок навыков (используйте [HTML5 Drag and Drop API](https://developer.mozilla.org/ru/docs/Web
Раздел 5. Интерактивная секция «Опыт работы»
Цель раздела: Научить создавать раскрывающиеся блоки с описанием опыта, используя события и CSS-анимации.
Теория: Как работает интерактивность
Ключевые концепции:
- Событие
click— отслеживание клика на элементе. - CSS-классы — управление видимостью через
display/max-height. - Плавные переходы — анимация с помощью
transition.
Почему именно так?
- Изменение классов через JS позволяет отделить логику от стилей.
- CSS-анимации работают эффективнее JS-анимаций.
Пошаговая инструкция
Шаг 1: Подготовка HTML
|
Шаг 2: Добавить CSS для анимации
|
Шаг 3: JavaScript-логика
|
Codepen-пример
Особенности:
- Плавная анимация раскрытия.
- Динамическое обновление иконки-индикатора.
- Поддержка нескольких элементов.
Практическое задание
Задача: Добавить интерактивность в секцию опыта своего CV.
-
Базовый вариант:
- Реализовать раскрытие/скрытие описания.
- Добавить консоль-лог при клике:
console.log('Состояние блока:', description.classList.contains('open'));
-
Продвинутый вариант:
- Сохранять состояние блоков в
localStorage.// После перезагрузки страницы document.querySelectorAll('.experience-header').forEach(header => { const description = header.nextElementSibling; const isOpen = localStorage.getItem(header.textContent) === 'true'; if (isOpen) description.classList.add('open'); }); // При клике localStorage.setItem(header.textContent, description.classList.contains('open')); - Добавить анимацию вращения иконки:
.experience-header::before { content: '▶'; display: inline-block; transition: transform 0.3s; } .experience-description.open + .experience-header::before { transform: rotate(90deg); }
- Сохранять состояние блоков в
Частые ошибки
| Ошибка | Решение |
|---|---|
| Анимация не работает | Убедитесь, что max-height задан в px, а не %. |
| Контент выходит за границы | Добавьте overflow: hidden к контейнеру. |
| Несколько блоков открываются одновременно | Используйте event.target, чтобы определить конкретный элемент. |
Советы по отладке
- Проверяйте классы через Инструменты разработчика (F12 → Elements).
- Используйте
console.log(event.target), чтобы убедиться, что клик обрабатывается правильно. - Тестируйте анимации на реальном контенте — высота
max-heightдолжна быть больше фактической высоты блока.
Дополнительные идеи
-
Аккордеон-меню — закрывать предыдущий блок при открытии нового:
header.addEventListener('click', () => { document.querySelectorAll('.experience-description').forEach(desc => { if (desc !== description) desc.classList.remove('open'); }); }); -
Анимация opacity — комбинируйте
max-heightиopacityдля эффекта “появления”.
Что проверять после раздела
- Описание раскрывается/скрывается по клику.
- Анимация плавная, без рывков.
- Состояние блоков сохраняется (для продвинутой версии).
Раздел 6. Валидация формы контактов
Цель раздела: Научить проверять данные формы на стороне клиента, отображать ошибки и предотвращать некорректные действия пользователя.
Теория: Зачем нужна валидация?
- Основная задача:
- Обеспечить корректность данных (например, email содержит «@»).
- Улучшить UX через мгновенную обратную связь.
- Методы валидации:
- Нативная HTML5-валидация (атрибуты
required,type="email"). - Кастомная валидация через JavaScript.
- Нативная HTML5-валидация (атрибуты
Пошаговая инструкция
Шаг 1: Подготовка HTML-формы
|
Шаг 2: JavaScript-обработчик отправки
|
Codepen-пример
Рабочий пример
Особенности:
- Подсветка невалидных полей:
.invalid { border: 2px solid #e74c3c !important; } - Динамическое обновление ошибок.
Практическое задание
Задача: Реализовать валидацию для своей формы.
-
Базовый вариант:
- Проверка пустых полей.
- Валидация email на наличие «@» и домена.
-
Продвинутый вариант:
- Валидация номера телефона через регулярное выражение:
function validatePhone(phone) { return /^\+?(\d{1,3})?[-. ]?(\(?\d{3}\)?[-. ]?)?[\d-. ]{7,10}$/.test(phone); } - AJAX-отправка данных на моковый API:
fetch('https://jsonplaceholder.typicode.com/posts', { method: 'POST', body: JSON.stringify({ name, email }) });
- Валидация номера телефона через регулярное выражение:
Частые ошибки
| Ошибка | Решение |
|---|---|
| Форма перезагружает страницу | Добавьте e.preventDefault(). |
| Регулярное выражение не работает | Проверьте его на RegExr. |
| Ошибки не сбрасываются | Добавьте errorMessage.style.display = 'none' перед проверками. |
Советы по отладке
- Используйте
console.log(email)для вывода введенных данных. - Тестируйте регулярные выражения отдельно (например, в RegExr).
- Проверьте, что
idэлементов совпадают в HTML и JS.
Дополнительные идеи
- Валидация в реальном времени — проверка при вводе:
document.getElementById('email').addEventListener('input', () => { const email = document.getElementById('email').value; if (!validateEmail(email)) { showError('Некорректный email'); } }); - Кастомные подсказки — всплывающие тултипы вместо
alert().
Что проверять после раздела
- Форма не отправляется при ошибках.
- Сообщения об ошибках четкие и понятные.
- Поля подсвечиваются при невалидных данных.
Раздел 7. Дополнительные идеи для CV
Цель раздела: Вдохновить участников на самостоятельное развитие проекта, показав возможности расширения функционала с помощью JavaScript.
Теория: Куда двигаться дальше?
Ключевые направления:
- Анимации — улучшение UX через визуальные эффекты.
- Работа с API — динамическая загрузка данных (погода, курсы валют).
- Интерактивность — drag-and-drop, кастомные виджеты.
Почему это важно?
- Дополнительные фичи делают CV уникальным.
- Позволяют продемонстрировать навыки работы с разными технологиями.
Идеи для реализации
Идея 1: Таймер до цели
Задача: Показать, сколько дней осталось до достижения карьерной цели.
|
|
Идея 2: Виджет погоды
Задача: Отображать текущую погоду через API.
|
Идея 3: Drag-and-Drop для секций
Задача: Позволить менять порядок секций CV.
|
|
Идея 4: Анимация прогресс-бара навыков
Задача: Визуализировать уровень владения технологиями.
|
|
|
Codepen-примеры
Практическое задание
Задача: Выбрать 1-2 идеи и реализовать их в своем CV.
Базовый уровень:
- Добавить таймер до цели.
- Реализовать анимацию при скролле (например, появление секций).
Продвинутый уровень:
- Интегрировать API (погода, GitHub-статистика).
- Создать кастомный аудиоплеер для раздела «Хобби».
Частые ошибки
| Ошибка | Решение |
|---|---|
| API не возвращает данные | Проверьте CORS-политику и API-ключи. |
| Анимации тормозят | Используйте will-change или transform. |
| Drag-and-Drop не работает | Добавьте атрибут draggable="true". |
Советы по реализации
- Для анимаций используйте GSAP или Animate.css.
- Для работы с API начните с моковых данных через
json-server. - Тестируйте интерактивность на мобильных устройствах.
Полезные ресурсы
- OpenWeatherMap API — погода.
- GitHub API — статистика репозиториев.
- CSS Tricks — готовые решения для анимаций.
Итог
Участники получат готовое портфолио, которое можно:
- Разместить на GitHub Pages.
- Дополнять новыми разделами (блог, пет-проекты).
- Использовать как шаблон для других проектов.