Капстон: модальное окно

Основы фронтенд разработки

Капстон: модальное окно

Продолжительность: 30 мин

Поиск и фильтрация работают. Теперь добавим модальное окно — при клике на карточку пользователь видит полную информацию о месте.

Требования

HTML-структура модального окна

  • Добавьте в index.html один элемент модального окна. Он должен существовать в DOM с самого начала, но быть скрыт.
  • Структура внутри: крупное изображение, бейдж категории, название, адрес, рейтинг, полное описание, кнопка закрытия.
  • За пределами внутреннего блока — полупрозрачный backdrop, клик по которому закрывает модалку.

Рекомендуемая HTML-структура. Внешний элемент — сам backdrop (полупрозрачный оверлей на весь экран). Внутри него — блок с контентом. Это удобно: клик вне блока с контентом будет кликом по backdrop:

<div class="modal" id="modal"> <div class="modal__content"> <button class="modal__close" id="modalClose">×</button> <img class="modal__image" id="modalImage" src="" alt=""> <div class="modal__body"> <span class="modal__category" id="modalCategory"></span> <h2 class="modal__title" id="modalTitle"></h2> <p class="modal__address" id="modalAddress"></p> <div class="modal__rating" id="modalRating"></div> <p class="modal__description" id="modalDescription"></p> </div> </div> </div>
html

CSS для модалки: position: fixed; inset: 0 — фиксирует оверлей на весь экран. Скрытое состояние удобнее всего реализовать через opacity: 0; pointer-events: none, а видимое — через класс modal--open с opacity: 1; pointer-events: auto. Это позволяет анимировать через transition: opacity.

Открытие и закрытие

  • Клик по карточке открывает модалку с данными именно этой достопримечательности.
  • Используйте делегирование: один обработчик на контейнере сетки, а не по обработчику на каждой карточке.
  • Кнопка закрытия (×) закрывает модалку.
  • Клик по backdrop закрывает модалку. Клик по содержимому модалки — нет.
  • Нажатие Escape закрывает модалку.
  • Пока модалка открыта, страница под ней не прокручивается (document.body получает нужный стиль).
  • После закрытия прокрутка восстанавливается.

Как найти нужный объект при делегировании. Карточка имеет data-id. При клике найдите ближайшую карточку через closest, возьмите id и найдите объект в state.attractions:

grid.addEventListener('click', (e) => { const card = e.target.closest('.card'); if (!card) return; const id = Number(card.dataset.id); const attraction = state.attractions.find(a => a.id === id); openModal(attraction); });
js

Как отличить клик по backdrop от клика по контенту. Слушайте клик на самом модальном оверлее и проверяйте e.target:

modal.addEventListener('click', (e) => { if (e.target === modal) closeModal(); // кликнули именно по backdrop, не по содержимому });
js

Блокировка прокрутки. Стандартный приём — добавить overflow: hidden на body:

function openModal(attraction) { document.body.style.overflow = 'hidden'; modal.classList.add('modal--open'); // заполнить поля... } function closeModal() { document.body.style.overflow = ''; modal.classList.remove('modal--open'); }
js

Анимация

  • Открытие и закрытие должны быть анимированы: плавное появление backdrop и самого окна.
  • Реализуйте через CSS-классы и transition — не через JS-анимацию.

CSS-подход к анимации. Базовое состояние — модалка невидима и некликабельна. Класс modal--open делает её видимой. Переход прописывается в базовом состоянии:

.modal { position: fixed; inset: 0; background: rgba(0, 0, 0, 0.6); opacity: 0; pointer-events: none; transition: opacity 0.25s ease; display: flex; align-items: center; justify-content: center; } .modal--open { opacity: 1; pointer-events: auto; } .modal__content { transform: translateY(20px); transition: transform 0.25s ease; } .modal--open .modal__content { transform: translateY(0); }
css

Наполнение данными

  • При открытии модалки заполняйте её содержимое данными из объекта достопримечательности.
  • Храните ссылку на текущий открытый объект в state — она пригодится в следующем этапе (для кнопки избранного внутри модалки).

Заполнение полей модалки. Прямое обращение по id удобнее querySelector внутри функции:

function fillModal(attraction) { document.getElementById('modalImage').src = attraction.image; document.getElementById('modalImage').alt = attraction.name; document.getElementById('modalTitle').textContent = attraction.name; document.getElementById('modalCategory').textContent = attraction.category; document.getElementById('modalAddress').textContent = attraction.address; document.getElementById('modalRating').textContent = `${attraction.rating}`; document.getElementById('modalDescription').textContent = attraction.description; }
js

Продвинутое задание — URL hash

Реализуйте навигацию через хэш URL: когда модалка открывается, добавляйте в адресную строку #attraction-1 (где 1 — id места). При закрытии убирайте хэш. При загрузке страницы проверяйте хэш и если он есть — автоматически открывайте нужную модалку.

Это позволяет делиться прямой ссылкой на конкретное место. Изучите:

Ожидаемый результат

  • клик по карточке открывает модалку с данными этой достопримечательности
  • в модалке есть изображение, категория, название, адрес, рейтинг, описание
  • модалка закрывается по кнопке ×, клику по backdrop и клавише Escape
  • пока модалка открыта, страница не прокручивается
  • открытие и закрытие анимированы
  • клик внутри модалки не закрывает её

Это платный урок

Купите полный доступ к курсу чтобы просматривать данный контент

Основы фронтенд разработки

Полный курс по основам веб-разработки с нуля: HTML, CSS и JavaScript. Вы сверстаете адаптивный лендинг, освоите анимации и работу с DOM, а в финале соберёте самостоятельный проект — интерактивный путеводитель по Санкт-Петербургу.

4990 Скидка 20%
3990

Безопасные платежи обрабатываются сервисом Юкасса

Комментарии

Войдите, чтобы оставить комментарий