Часть 3. Построение от инфраструктуры до готового приложения

С возвращением!

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

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

Осталось два шага для заполнения заявки.

  1. Нам нужно закодировать функции обратного вызова, которыебудут использоваться двумя прослушивателями событий, упомянутыми в Части 2.
  2. Нам нужно написать прослушиватели событий, которые будут вызывать функции обратного вызова для выполнения своей работы.

Шаг 7: Кодирование функций обратного вызова

Давайте на мгновение задумаемся о том, что должны делать эти функции обратного вызова. Мы знаем, что они прикреплены в качестве аргументов к двум прослушивателям событий, один из которых прослушивает событие щелчка на странице Проверка почтовых индексов. strong>, а другой прослушивает событие щелчка накнопке Reset.

Мы продолжим код именно с того места, на котором вы остановились в конце Части 2.

На рис. 1 ниже показаны оставшиеся соответствующие строки начального кода, загруженного в Часть 2:

Для кнопки Подтвердить почтовые индексы нам нужна функция обратного вызова, которая
заменит содержимое сообщением по умолчанию НЕТ СОВПАДЕНИЯ и заполнит его родительский вместо окна прокрутки с действительными совпадениями почтового индекса.

Функция populateResultBox()
Возвращаясь к рисунку 1, замените комментарий в строке 65 (строка 108 в исправленном коде). со следующим кодом:

const populateResultBox = () => {
  
  resultBox.classList.remove('default-result');
  resultBox.removeChild(placeHolder);
  resultBox.classList.add('custom-scrollbar');
  createParagraphText();
  // Create paragraphs and set textContent only
  // if not already created. Prevents doubling
  // of result data if old paragraphs have not
  // yet been garbage collected.
  if (paragraphs.length === 0) {
    createParagraphs();
  }
  // Append all result paragraphs to resultBox.
  appendParagraphs(resultBox, paragraphs);
};

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

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

В листинге 1 кода ниже показан элемент HTML, на который ссылается resultBox:

Вы могли вспомнить из Части 2 листинг кода, который начинался с элемента
<div id="getResults">, который содержит весь виджет с
двумя кнопками и <p> элемент с сообщением NO MATCH, показанным в листинге 1 выше.

Нам нужно немного погрузиться в код CSS, чтобы полностью понять, что изменяется с помощью populateResultBox().

Взгляните на листинг 2 ниже:

Как видите, класс .default-result задает серый фон. Поскольку этот фон является частью заполнителя для результатов, которые должны заполнить resultBox, мы хотим его очистить.

Теперь давайте посмотрим на первую строку кода в populateResultBox() функции обратного вызова:

resultBox.classList.remove('default-result');

Как мы знаем, resultBox объект захватывает <div id="results">, показанный в листинге 1 кода.

В объектной модели документа (DOM) элементы HTML имеют свойство classList, которое отслеживает все классы CSS связаны
с ними.

remove() метод, связанный со свойством classList, делает именно то, о чем говорит: он удаляет переданный ему класс из classList. Это не означает, что класс удален из таблицы стилей CSS. Это действительно означает, что веб-страница, отображаемая в вашем браузере, больше не будет отображаться серым фоном в прокручиваемом окне результатов.

Теперь давайте рассмотрим нашу вторую строку кода:

resultBox.removeChild(placeHolder);

Эта строка кода связана с узлами в дереве DOM. Как вы
возможно помните ранее, placeHolderявляется >узел DOM, который захватывает
<p class="default-message" id="message">no match</p> .

Этот абзац представляет собой сообщение NO MATCH, отображаемое на начальном экране нашего приложения. Очевидно, нам нужно удалить это с нашего дисплея.

removeChild() метод удаляет дочерний узел из родительского узла placeHolder дочерний узел resultBox. Как и в случае remove() метода выше, removeChild() оставляет абзац в HTML нетронутым. Он просто удален из нашего живого дисплея.

Теперь давайте рассмотрим нашу третью строку кода:

resultBox.classList.add('custom-scrollbar');

Здесь мы делаем что-то совсем другое. Здесь мы добавляем класс CSS
в resultBox. В листинге 3 ниже показан код для CSS
класс .custom-scrollbar:

Не углубляясь в приведенный выше код, все, что нам нужно знать, это то, что этот класс устанавливает стили переднего плана и фона для полосы прокрутки в resultBox после ее заполнения. Для тех, кто заинтересован в более глубоком изучении стилей, вышеприведенный стиль был основан на работе CSS Tricks (Coyier, «Использование пользовательских свойств для стилей полос прокрутки в CSS »).

Метод add(), связанный со свойством classList , в отличие от метода remove(), который мы видели несколько минут назад, добавляет CSS class в resultBox.

Оставшийся код в populateResultBox() функции обратного вызова уже рассмотрен в Части 2 Шаг 6 этого руководства.

Теперь мы можем заняться кодированием функции обратного вызова depopulateResultBox() . Как вы могли догадаться, цель этой функции — удалить все абзацы, которые заполняли resultBox, и восстановить сообщение по умолчанию и связанные с ним стили.

Возвращаясь к рисунку 1,замените комментарий в строке 69 (строка 133 в исправленном коде) функцией ниже:

const depopulateResultBox = () => {
  while (resultBox.firstChild) {
    resultBox.removeChild(resultBox.firstChild);
  }
  resultBox.classList.remove('custom-scrollbar');
  resultBox.classList.add('default-result');
  resultBox.appendChild(placeHolder);
};

Мы встречали все методы этой функции, когда кодировали populateResultBox() вспомогательную функцию выше. Итак, вот краткий обзор
того, что происходит в этом коде:

  1. Мы начинаем с цикла while, который принимает единственный аргумент — resultBox.firstChild. Мы уже знаем, что resultBox является узлом DOM. Таким образом, он предоставляет свойства и методы. Свойство firstChild фиксирует первый дочерний элемент resultBox, который будет первым абзацем в resultBox.
  2. Аргумент в этом цикле while — это логическое значение, которое принимает значение true, если в firstChild есть узел абзаца firstChild. сильный>результат. Каждый раз в цикле выполняется resultBox.removeChild(resultBox.firstChild);, удаляющий один абзац. На каждой итерации цикла следующий абзац в строке становится первым дочерним элементом. Как только не останется firstChild, цикл завершается, так как не остается абзацев.
  3. После того, как все абзацы будут удалены, три оставшиеся строки кода
    за пределами цикла while удалят класс .custom-scrollbar
    из resultBox,добавят >.default-result класс, таким образом восстанавливая серый фон, и, наконец, использует appendChild() метод для восстановления
    НЕ СОВПАДЕНИЯ сообщение.

Теперь мы завершили наши функции обратного вызова и готовы перейти к последнему шагу — кодированию прослушивателей событий для проверки почтовых индексов и >Сброс кнопок.

Шаг 8. Кодирование прослушивателей событий

Теперь мы подошли к последнему шагу в завершении нашего приложения — кодированию прослушивателей событий для наших кнопок.

Для начала я хотел бы вспомнить два объявленных объекта-узла, которые мы создали в начале Части 2, Регулярные выражения — обряд посвящения. : от теории к практике»:

const resultButton = document.getElementById('validate');
const resetButton = document.getElementById('reset');

Эти две строки кода являются нашей отправной точкой, так как они понадобятся нам для создания наших слушателей событий.

resultButton — это узел DOM, который фиксирует
<button class="controlButton" id="validate"> элемент в нашем
index.htmlфайл.

resetButton – это узел DOM, который захватывает
<button class="controlButton" id="reset"> элемент.

С этой информацией мы можем начать. Возвращаясь к рисунку 1,замените комментарий в строке 75 (строка 146 в исправленном коде) кодомниже:

resultButton.addEventListener('click', populateResultBox);

Используя DOM-узел resultButton, мы связываем с ним метод addEventListener(). Как видите, этот метод принимает два аргумента.

Первый указывает, какой тип события следует прослушивать (существует несколько различных типов). У нас есть событие щелчка, что означает, что JavaScript будет прослушивать любые щелчки мыши на resultButton.

Второй — функция обратного вызова, которая выполняется при обнаружении события щелчка. Эта функция обратного вызова может быть анонимной функцией, включенной в качестве второго аргумента. В нашем случае функция обратного вызова — это populateResultBox().

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

Если вы еще этого не сделали, откройте файл index.html в своем любимом браузере. Если у вас уже открыт файл, обязательно обновите браузер.

Нажмите кнопку Проверить почтовые индексы.

Ваш экран должен выглядеть примерно так, как показано ниже на Рис. 2:

Теперь давайте напишем прослушиватель событий для кнопки Сброс.

Возвращаясь к рисунку 1, замените комментарий в строке 79 (строка 150 в исправленном коде) следующим кодом:

resetButton.addEventListener('click', depopulateResultBox);

Этот прослушиватель событий также прослушивает событие щелчка, но на этот раз для нашей кнопки Сброс, и вызывает depopulateResultBox() функцию обратного вызова, чтобы сбросить нашу страницу в исходное состояние.

Чтобы проверить это, обновите браузер. Теперь нажмите кнопку Проверить почтовые индексы. Как только вы увидите, что resultBox заполнен почтовым индексом, нажмите кнопку Reset.

Если все пойдет по плану, ваш экран должен вернуться в исходное состояние с сообщением НЕТ СОВПАДЕНИЯ, отображаемым в окне результатов.

Заключение

ПОЗДРАВЛЯЕМ! Вы завершили демонстрационную проверку почтового индекса Одностраничное приложение (SPA).

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

Вы также можете просмотреть живое приложение здесь, на codepen.io.

Следующие шаги

Теперь, когда у вас есть функциональное демонстрационное веб-приложение, которое возвращает действительные почтовые индексы из тестовой строки, что вы можете сделать дальше?

Поэкспериментируйте с готовым кодом, который у вас есть. Вот несколько предложений:

  1. Поэкспериментируйте с дальнейшим отделением вспомогательных функций от
    данных, с которыми они работают, как в моем примере с createParagraphs() функцией. .
  2. Подумайте о том, как сделать это по-настоящему интерактивным приложением, в котором пользователь просто вводит тестовую строку и нажимает кнопку Проверить почтовые индексы, чтобы получить результаты. .

Наконец, не стесняйтесь разветвлять мой репозиторий и создавать свою собственную версию.

Удачного программирования!

Дополнительные материалы на PlainEnglish.io. Подпишитесь на нашу бесплатную еженедельную рассылку новостей. Подпишитесь на нас в Twitter и LinkedIn. Посетите наш Community Discord и присоединитесь к нашему Коллективу талантов.