You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
Web-Dev-For-Beginners/translations/ru/7-bank-project/1-template-route
Lee Stott 2daab5271b
Update Quiz Link
3 weeks ago
..
README.md Update Quiz Link 3 weeks ago
assignment.md 🌐 Update translations via Co-op Translator 4 weeks ago

README.md

Создание банковского приложения. Часть 1: HTML-шаблоны и маршруты в веб-приложении

Викторина перед лекцией

Викторина перед лекцией

Введение

С появлением JavaScript в браузерах веб-сайты стали более интерактивными и сложными, чем когда-либо. Веб-технологии теперь часто используются для создания полноценных приложений, которые работают прямо в браузере и называются веб-приложениями. Поскольку веб-приложения очень интерактивны, пользователи не хотят ждать полной перезагрузки страницы каждый раз, когда выполняется какое-либо действие. Именно поэтому JavaScript используется для обновления HTML напрямую через DOM, чтобы обеспечить более плавный пользовательский опыт.

В этом уроке мы заложим основы для создания банковского веб-приложения, используя HTML-шаблоны для создания нескольких экранов, которые можно отображать и обновлять без необходимости перезагрузки всей HTML-страницы.

Предварительные требования

Для тестирования веб-приложения, которое мы будем создавать в этом уроке, вам понадобится локальный веб-сервер. Если у вас его нет, вы можете установить Node.js и использовать команду npx lite-server из папки вашего проекта. Это создаст локальный веб-сервер и откроет ваше приложение в браузере.

Подготовка

На вашем компьютере создайте папку с именем bank и файл с именем index.html внутри нее. Мы начнем с этого шаблона HTML:

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Bank App</title>
  </head>
  <body>
    <!-- This is where you'll work -->
  </body>
</html>

HTML-шаблоны

Если вы хотите создать несколько экранов для веб-страницы, одним из решений будет создание отдельного HTML-файла для каждого экрана, который вы хотите отобразить. Однако это решение имеет некоторые недостатки:

  • При переключении экрана необходимо перезагружать весь HTML, что может быть медленным.
  • Сложно делиться данными между различными экранами.

Другой подход — использовать только один HTML-файл и определить несколько HTML-шаблонов с помощью элемента <template>. Шаблон — это повторно используемый блок HTML, который не отображается браузером и должен быть создан во время выполнения с помощью JavaScript.

Задача

Мы создадим банковское приложение с двумя экранами: страницей входа и панелью управления. Сначала добавим в тело HTML элемент-заполнитель, который мы будем использовать для отображения различных экранов нашего приложения:

<div id="app">Loading...</div>

Мы присваиваем ему id, чтобы позже было проще найти его с помощью JavaScript.

Совет: поскольку содержимое этого элемента будет заменено, мы можем добавить сообщение или индикатор загрузки, который будет отображаться, пока приложение загружается.

Далее добавим ниже HTML-шаблон для страницы входа. Пока мы добавим туда только заголовок и секцию с ссылкой, которую будем использовать для навигации.

<template id="login">
  <h1>Bank App</h1>
  <section>
    <a href="/dashboard">Login</a>
  </section>
</template>

Затем добавим еще один HTML-шаблон для страницы панели управления. Эта страница будет содержать различные секции:

  • Заголовок с названием и ссылкой для выхода
  • Текущий баланс банковского счета
  • Список транзакций, отображаемый в таблице
<template id="dashboard">
  <header>
    <h1>Bank App</h1>
    <a href="/login">Logout</a>
  </header>
  <section>
    Balance: 100$
  </section>
  <section>
    <h2>Transactions</h2>
    <table>
      <thead>
        <tr>
          <th>Date</th>
          <th>Object</th>
          <th>Amount</th>
        </tr>
      </thead>
      <tbody></tbody>
    </table>
  </section>
</template>

Совет: при создании HTML-шаблонов, если вы хотите увидеть, как они будут выглядеть, вы можете закомментировать строки <template> и </template>, заключив их в <!-- -->.

Почему, по вашему мнению, мы используем атрибуты id для шаблонов? Могли бы мы использовать что-то другое, например классы?

Отображение шаблонов с помощью JavaScript

Если вы попробуете открыть текущий HTML-файл в браузере, вы увидите, что он застрял на отображении Loading.... Это потому, что нам нужно добавить немного JavaScript-кода, чтобы создать и отобразить HTML-шаблоны.

Создание шаблона обычно выполняется в 3 этапа:

  1. Найти элемент шаблона в DOM, например, используя document.getElementById.
  2. Клонировать элемент шаблона, используя cloneNode.
  3. Присоединить его к DOM под видимым элементом, например, используя appendChild.

Почему нам нужно клонировать шаблон перед его присоединением к DOM? Что, по вашему мнению, произойдет, если мы пропустим этот шаг?

Задача

Создайте новый файл с именем app.js в папке вашего проекта и импортируйте этот файл в секцию <head> вашего HTML:

<script src="app.js" defer></script>

Теперь в app.js мы создадим новую функцию updateRoute:

function updateRoute(templateId) {
  const template = document.getElementById(templateId);
  const view = template.content.cloneNode(true);
  const app = document.getElementById('app');
  app.innerHTML = '';
  app.appendChild(view);
}

Здесь мы выполняем именно те 3 шага, которые описаны выше. Мы создаем шаблон с id templateId и помещаем его клонированное содержимое в наш заполнитель приложения. Обратите внимание, что нам нужно использовать cloneNode(true), чтобы скопировать всю поддеревьевую структуру шаблона.

Теперь вызовите эту функцию с одним из шаблонов и посмотрите результат.

updateRoute('login');

Какова цель этого кода app.innerHTML = '';? Что произойдет без него?

Создание маршрутов

Когда мы говорим о веб-приложении, мы называем маршрутизацией намерение сопоставить URL с определенными экранами, которые должны быть отображены. На веб-сайте с несколькими HTML-файлами это делается автоматически, так как пути к файлам отражаются в URL. Например, с этими файлами в папке вашего проекта:

mywebsite/index.html
mywebsite/login.html
mywebsite/admin/index.html

Если вы создадите веб-сервер с корнем mywebsite, сопоставление URL будет следующим:

https://site.com            --> mywebsite/index.html
https://site.com/login.html --> mywebsite/login.html
https://site.com/admin/     --> mywebsite/admin/index.html

Однако для нашего веб-приложения мы используем один HTML-файл, содержащий все экраны, поэтому это поведение по умолчанию нам не поможет. Нам нужно создать это сопоставление вручную и обновить отображаемый шаблон с помощью JavaScript.

Задача

Мы будем использовать простой объект для реализации карты между путями URL и нашими шаблонами. Добавьте этот объект в начало вашего файла app.js.

const routes = {
  '/login': { templateId: 'login' },
  '/dashboard': { templateId: 'dashboard' },
};

Теперь немного изменим функцию updateRoute. Вместо того чтобы передавать непосредственно templateId в качестве аргумента, мы хотим сначала получить текущий URL, а затем использовать нашу карту для получения соответствующего значения templateId. Мы можем использовать window.location.pathname, чтобы получить только секцию пути из URL.

function updateRoute() {
  const path = window.location.pathname;
  const route = routes[path];

  const template = document.getElementById(route.templateId);
  const view = template.content.cloneNode(true);
  const app = document.getElementById('app');
  app.innerHTML = '';
  app.appendChild(view);
}

Здесь мы сопоставили маршруты, которые мы объявили, с соответствующими шаблонами. Вы можете проверить, что это работает правильно, изменив URL вручную в вашем браузере.

Что произойдет, если вы введете неизвестный путь в URL? Как мы могли бы решить эту проблему?

Добавление навигации

Следующий шаг для нашего приложения — добавить возможность перехода между страницами без необходимости вручную изменять URL. Это подразумевает две вещи:

  1. Обновление текущего URL
  2. Обновление отображаемого шаблона на основе нового URL

Мы уже позаботились о второй части с помощью функции updateRoute, поэтому нам нужно разобраться, как обновить текущий URL.

Мы будем использовать JavaScript, а точнее history.pushState, который позволяет обновить URL и создать новую запись в истории браузера без перезагрузки HTML.

Примечание: хотя HTML-элемент якоря <a href> можно использовать самостоятельно для создания гиперссылок на разные URL, он по умолчанию заставляет браузер перезагружать HTML. Необходимо предотвратить это поведение при обработке маршрутизации с помощью пользовательского JavaScript, используя функцию preventDefault() для события клика.

Задача

Давайте создадим новую функцию, которую можно использовать для навигации в нашем приложении:

function navigate(path) {
  window.history.pushState({}, path, path);
  updateRoute();
}

Этот метод сначала обновляет текущий URL на основе указанного пути, затем обновляет шаблон. Свойство window.location.origin возвращает корень URL, позволяя нам реконструировать полный URL из указанного пути.

Теперь, когда у нас есть эта функция, мы можем решить проблему, которая возникает, если путь не соответствует ни одному из определенных маршрутов. Мы изменим функцию updateRoute, добавив резервный вариант для одного из существующих маршрутов, если мы не можем найти совпадение.

function updateRoute() {
  const path = window.location.pathname;
  const route = routes[path];

  if (!route) {
    return navigate('/login');
  }

  ...

Если маршрут не найден, мы теперь перенаправляем на страницу login.

Теперь давайте создадим функцию для получения URL при клике на ссылку и предотвращения стандартного поведения браузера для ссылок:

function onLinkClick(event) {
  event.preventDefault();
  navigate(event.target.href);
}

Давайте завершим систему навигации, добавив привязки к нашим ссылкам Login и Logout в HTML.

<a href="/dashboard" onclick="onLinkClick(event)">Login</a>
...
<a href="/login" onclick="onLinkClick(event)">Logout</a>

Объект event выше захватывает событие click и передает его в нашу функцию onLinkClick.

Используя атрибут onclick, привяжите событие click к JavaScript-коду, здесь вызову функции navigate().

Попробуйте нажать на эти ссылки, теперь вы должны иметь возможность переходить между различными экранами вашего приложения.

Метод history.pushState является частью стандарта HTML5 и реализован во всех современных браузерах. Если вы создаете веб-приложение для старых браузеров, есть трюк, который можно использовать вместо этого API: используя хэш (#) перед путем, вы можете реализовать маршрутизацию, которая работает с обычной навигацией по якорям и не перезагружает страницу, так как ее цель — создавать внутренние ссылки внутри страницы.

Обработка кнопок "Назад" и "Вперед" в браузере

Использование history.pushState создает новые записи в истории навигации браузера. Вы можете проверить это, удерживая кнопку Назад вашего браузера, она должна отображать что-то вроде этого:

Скриншот истории навигации

Если вы попробуете несколько раз нажать кнопку "Назад", вы увидите, что текущий URL изменяется, и история обновляется, но тот же шаблон продолжает отображаться.

Это потому, что приложение не знает, что нам нужно вызвать updateRoute() каждый раз, когда история изменяется. Если вы посмотрите документацию history.pushState, вы увидите, что если состояние изменяется — то есть мы перешли на другой URL — событие popstate будет вызвано. Мы используем это, чтобы исправить проблему.

Задача

Чтобы убедиться, что отображаемый шаблон обновляется при изменении истории браузера, мы привяжем новую функцию, которая вызывает updateRoute(). Мы сделаем это в конце нашего файла app.js:

window.onpopstate = () => updateRoute();
updateRoute();

Примечание: мы использовали стрелочную функцию для объявления обработчика события popstate для краткости, но обычная функция будет работать так же.

Вот видео-обзор о стрелочных функциях:

Стрелочные функции

🎥 Нажмите на изображение выше, чтобы посмотреть видео о стрелочных функциях.

Теперь попробуйте использовать кнопки "Назад" и "Вперед" вашего браузера и убедитесь, что отображаемый маршрут теперь обновляется правильно.


🚀 Задание

Добавьте новый шаблон и маршрут для третьей страницы, которая показывает авторов этого приложения.

Викторина после лекции

Викторина после лекции

Обзор и самостоятельное изучение

Маршрутизация — одна из удивительно сложных частей веб-разработки, особенно по мере того, как веб переходит от поведения с обновлением страниц к обновлениям страниц в одностраничных приложениях. Прочитайте немного о том, как служба Azure Static Web App обрабатывает маршрутизацию. Можете ли вы объяснить, почему некоторые из описанных решений необходимы?

Задание

Улучшите маршрутизацию

Отказ от ответственности:
Этот документ был переведен с использованием сервиса автоматического перевода Co-op Translator. Хотя мы стремимся к точности, пожалуйста, учитывайте, что автоматические переводы могут содержать ошибки или неточности. Оригинальный документ на его родном языке следует считать авторитетным источником. Для получения критически важной информации рекомендуется профессиональный перевод человеком. Мы не несем ответственности за любые недоразумения или неправильные интерпретации, возникшие в результате использования данного перевода.