В JavaScript есть возможность создавать модальные всплывающие окна с помощью трех функций — alert, prompt и confirm. В этой статье мы опишем каждую из этих функций и продемонстрируем несколько примеров. А также в конце статьи мы напишем игру в жанре текстовый квест на JavaScript, используя рассматриваемые функции.
Функция alert
Функция alert
— это функция в JavaScript, которая отображает всплывающее окно сообщением и единственной кнопкой «ОК», при нажатии на которую окно закрывается. Эта функция может принимать один параметр — текст, который выводится в модальном окне при срабатывании alert
. Значение любого типа, что передается в эту функцию, преобразуется в строку.
Синтаксис:
alert(message);
Пример:
alert('Демонстрация alert');
Демо:
Если нужен перенос на следующую строку, используется \n
:
alert('Демонстрация\nalert');
Запуск функции alert
останавливает выполнение JS-кода на той строке, где была вызвана функция, пока пользователь не нажмет кнопку «ОК». При этом блокируется вся страница — вы не можете совершать на ней какие-либо действия при открытом модальном окне.
Функцию alert
чаще всего применяют в служебных целях, когда нужно быстро показать какое-либо значение. Но, так как это окно имеет стандартный внешний вид, которому нельзя установить собственные стили, то использовать это модальное окно на работающем сайте не рекомендуется.
Функция confirm
Функция confirm
вызывает модальное окно сообщением и двумя кнопками «ОК» и «Отмена». Сообщением обычно является закрытый вопрос, на который можно ответить «да» либо «нет». Соответственно, возвращаемое значение функции confirm при нажатии на «ОК» будет true
(«да»), а при клике на «Отмена» — false
(«нет»).
Синтаксис:
const result = confirm(message); // в result будет либо true, либо false
Пример:
const result = confirm('Вы уверены, что хотите удалить эту запись?'); if (result) { // Логика удаления записи } else { // Логика отмены удаления записи, например, вывод об этом сообщения }
Демо:
Функция prompt
Еще одна функция JavaScript, которая позволяет вызвать модальное окно — это prompt
. Модальное окно при запуске prompt
содержит помимо текста еще и текстовое поле для ввода значения. Окно имеет две кнопки: «ОК» и «Отмена».
Функция prompt
может принимать на вход как один, так и два параметра. Первый параметр — это текст, отображающийся во всплывающем окне. Этот текст обычно содержит какой-нибудь вопрос, ответ на который пользователю нужно ввести в текстовое поле. Второй опциональный параметр — значение по умолчанию, которое устанавливается в текстовое поле.
Синтаксис без значения по умолчанию:
const result = prompt(message); // в result будет значение из текстового поля
Синтаксис со значением по умолчанию:
const result = prompt(message, defaultFieldValue);
Таким образом, с помощью prompt мы можем запросить у посетителя некоторую информацию. При нажатии на «ОК» значение, установленное в поле, будет возвращено функцией prompt
и окно закроется. Тип возвращаемого значения будет строкой. Если пользователь вводит число, то оно конвертируется в строку. Нажимая на кнопку «Отмена», мы просто закрываем окно и prompt
возвращает null
. Полученные данные можно использовать в JS-коде, например, распечатать на странице.
Пример:
const questions = [ 'Как вас зовут?', 'Почему вы решили войти в IT?', 'Какие языки программирования знаете?' ]; const answers = []; questions.forEach(function(question) { answers.push(question + '\n' + prompt(question)); }); alert('Ваши ответы: \n' + answers.join('\n'));
Демо:
Пример совместной работы alert, confirm и prompt: текстовый квест
Далее продемонстрируем работу трех рассматриваемых функций в одном примере — создадим игру жанра текстовый квест. Цель игры — при наступлении определенной ситуации выбирать из предложенных вариантов действий тот, что в итоге поспособствует главному герою выбраться в город.
Для показа ошибок, подсказок, сообщений о выигрыше, проигрыше либо завершении игры будет использоваться функция alert
. Пользователь сможет делать выбор из предложенных вариантов, благодаря функции prompt
. Чтобы закончить игру досрочно, нужно будет нажать кнопку «Отмена» модального окна, вызванного функцией prompt. После этого появится окно функции confirm
с просьбой подтвердить выход из игры.
Логика связей уровней игры находится в объекте levels
, в который включены другие объекты, представляющие каждый уровень. Для лучшего понимания подробно разберем шаблон такого объекта:
1 : { 'text': 'Текст уровня', 'options': [['Первый вариант действия', 2], ['Второй вариант действия', 3]], 'status': Status.Process }
Объект имеет уникальный ключ, который является идентификатором уровня. В примере выше — это 1
. Значение объекта уровня — также объект, имеющий следующие содержимое:
text
— текст уровня (вопрос либо сообщение о победе или проигрыше);options
— варианты действий, каждый из которых включает в себя текст варианта иid
следующего уровня для перехода в случае выбора определенного варианта;status
— текущий статус уровня, который может иметь три значения, определяющие уровень как победный (win
), проигрышный (lose
) либо обозначающий, что игра продолжается (process
).
Все статусы находятся в отдельном объекте, который работает как перечисление.
Логика работы игры находится в функции handleLevel
, использующей рекурсивный вызов (вызывающей саму себя), так как функционал обработки каждого уровня одинаков. Кроме того, функция handleLevel использует небольшую вспомогательную функцию findNextLevelId
для поиска идентификатора следующего уровня.
Таким образом, уровни текстового квеста легко изменить — достаточно правильно подкорректировать объект levels. Однако функция handleLevel
не будет нуждаться в изменениях.
Если мы хотим начать игру по нажатию на кнопку, при наступлении события нажатия на эту кнопку мы должны запустить функцию handleLevel
с передачей ей в качестве параметра объекта levels, что и сделано в нашем примере. В качестве второго параметра по умолчанию установлена единица, то есть игра начнется с первого уровня.
В этот текстовый квест можно поиграть прямо на текущем сайте, нажав на кнопку «Старт игры», которая расположена после нижеуказанного JS-кода игры.
Код игры:
// Запускаем игры по нажатию на кнопку document.getElementById('demoAlertQuestButton').addEventListener('click', function() { handleLevel(levels); }); // Значения status: // process — игра продолжается // win — игра закончена, вы победили // lose — игра закончена, вы проиграли const Status = { Process: 'process', Win: 'win', Lose: 'lose' }; const levels = { 1 : { 'text': 'Вы просыпаетесь в неизвестном темном помещении. Голова болит. Вы не помните, как сюда попали. Нужно найти выход. Куда пойдете?', 'options': [['В приоткрытую дверь', 2], ['Через окно', 3]], 'status': Status.Process }, // В приоткрытую дверь 2 : { 'text': 'Вы тихо подходите к двери, аккуратно ее открываете, осматриваетесь - никого. Выходите на улицу. Вы понимаете, что далеко от города. Вам нужно найти способ добраться до города. Слева вдалеке вы видите дорогу, справа - дворовая территория. Куда вы направитесь?', 'options': [['Налево к дороге', 4], ['Направо во двор', 5]], 'status': Status.Process }, // Через окно 3 : { 'text': 'Окно открыто. Вы пытаетесь вылезть через него, но случайно спотыкаетесь и падаете снаружи прямо на арматуру - вы погибаете. Вы проиграли!', 'status': Status.Lose }, // Налево к дороге 4 : { 'text': 'Вы бежите в сторону дороги. Добегаете до нее и замечаете быстро мчащийся в сторону города автомобиль. Вам нужно, чтобы водитель вас подобрал. Как вы поступите?', 'options': [['Станете на дорогу, яростно крича и требуя остановиться', 6], ['Спокойно махнете рукой, прося остановиться', 7]], 'status': Status.Process }, // Направо во двор 5 : { 'text': 'Вы идете направо и замечаете лежащий на земле топор. Что будете делать?', 'options': [['Подберете топор', 8], ['Не подбирая топор, продолжите движение', 9]], 'status': Status.Process }, // Станете на дорогу, яростно крича и требуя остановиться 6 : { 'text': 'Вы напугали водителя. Он не захотел останавливаться и, пытаясь вас объехать, случайно задевает вас автомобилем на высокой скорости. Вы получаете травмы, не совместимые с жизнью. Вы проиграли!', 'status': Status.Lose }, // Спокойно махнете рукой, прося остановиться 7 : { 'text': 'Водитель решает остановиться, подбирает вас и доставляет в город. Вы выиграли!', 'status': Status.Win }, // Подберете топор 8 : { 'text': 'Вы подобрали топор и продолжили движение. За углом здания вы замечаете уродливое существо, которое занято пожиранием человеческого трупа и не видит вас. Через него нельзя пройти незамеченным. Какие выши действия?', 'options': [['Нападете', 10], ['Развернетесь и направитесь в сторону дороги', 4]], 'status': Status.Process }, // Не подбирая топор, продолжите движение 9 : { 'text': 'Вы не взяли топор и продолжили движение. За углом здания вы замечаете уродливое существо, которое занято пожиранием человеческого трупа и не видит вас. Через него нельзя пройти незамеченным. Какие выши действия?', 'options': [['Нападете', 11], ['Развернетесь и направитесь в сторону дороги', 4]], 'status': Status.Process }, // Нападете (с топором) 10 : { 'text': 'Вы напали на существо с топором, но сумели его только ранить и замедлить. Вам нужно быстро ретироваться. Куда побежите?', 'options': [['К высокому забору в нескольких метрах от вас', 12], ['Развернетесь и побежите в сторону дороги', 4]], 'status': Status.Process }, // Нападете (без топора) 11 : { 'text': 'Вы нападаете на существо без топора. Оно вас убивает. Вы проиграли!', 'status': Status.Lose }, // К высокому забору в нескольких метрах от вас 12 : { 'text': 'Вы бежите к высокому забору и пытаетесь перелезть через него. У вас не получается. Существо вас догоняет и убивает. Вы проиграли!', 'status': Status.Lose } }; function handleLevel(levels, currentLevelId = 1) { const currentLevel = levels[currentLevelId]; if (!currentLevel) { alert('Такого уровня не существует'); return; } if (currentLevel.status !== Status.Process) { alert(currentLevel.text); return; } let optionsString = ''; const allowedAnswerIds = []; currentLevel.options.forEach((option, key) => { let optionId = key + 1; let optionText = option[0]; optionsString += optionText + ' - введите ' + optionId + '\n'; allowedAnswerIds.push(optionId); }); const textWithOptions = currentLevel.text + '\n\n' + optionsString; const answer = prompt(textWithOptions); const isEmptyAnswer = (answer === ''); if (!answer && !isEmptyAnswer) { const isQuitConfirmed = confirm('Выйти из игры?'); if (isQuitConfirmed) { alert('Конец игры'); return; } const isGameOver = !handleLevel(levels, currentLevelId); if (isGameOver) { return; } } if (!allowedAnswerIds.includes(+answer)) { alert('Нужно ввести одно из следующих значений: ' + allowedAnswerIds.join()); return handleLevel(levels, currentLevelId); } const nextLevelId = findNextLevelId(currentLevel, answer); return handleLevel(levels, nextLevelId); } function findNextLevelId(currentLevel, answer) { const answerOption = currentLevel.options[answer - 1]; return answerOption[1]; }
Кнопка для запуска игры:
Заключение
В заключение отметим, что функции alert, confirm и prompt в современных сайтах используются редко. Их можно заменить более красивыми аналогами, стилизованными под дизайн конкретного сайта. В любом случае знать о существовании подобных функций стоит — они могут понадобиться для служебных целей во время разработки, изучения JavaScript либо, возможно, для каких-либо особых решений на рабочем сайте.