Что такое модальный диалог
Перейти к содержимому

Что такое модальный диалог

  • автор:

Dialog¶

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

Диалоги могут быть как модальными (взаимодействовать можно только с содержимым диалога), так и немодальными (взаимодействие с содержимым вне диалога все равно возможно). Модальные диалоги отображаются поверх остального содержимого страницы. Остальная часть страницы является inert и, по умолчанию, заслоняется полупрозрачным фоном.

Модальные диалоги¶

Приведем пример модального . Откройте диалог с помощью кнопки «Открыть модальный диалог». После открытия есть три способа закрыть диалог: клавиша escape, отправка формы с кнопкой, у которой установлен formmethod=»dialog» (или если у самой формы установлен method=»dialog» ), и метод HTMLDialogElement.close() .

Элемент HTMLDialogElement имеет три основных метода, а также все методы, унаследованные от HTMLElement .

1 2 3
dialog.show(); /* opens the dialog */ dialog.showModal(); /* opens the dialog as a modal */ dialog.close(); /* closes the dialog */ 

Поскольку данный был открыт с помощью метода HTMLDialogElement.showModal() , он является модальным диалогом. При открытии модального диалога деактивируется и затемняется все, кроме самого диалога. Если навести курсор на пользовательский интерфейс вне диалога, то можно заметить, что все элементы ведут себя так, как будто установлен pointer-events: none; ; даже кнопка, открывающая диалог, не реагирует на взаимодействия.

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

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

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

Фон, заслоняющий все остальное, кроме диалога, можно стилизовать с помощью псевдоэлемента ::backdrop . Фон отображается только при отображении с помощью метода .showModal() . Этот псевдоэлемент соответствует всем фонам, включая тот, который отображается при использовании FullScreen API, например, при просмотре видео в полноэкранном режиме, соотношение сторон которого не совпадает с соотношением сторон экрана или монитора.

Немодальные диалоги¶

Аналогичным образом открывается диалог с помощью HTMLDialogElement.show() , но без добавления фона и без инертности. Клавиша escape не закрывает немодальные диалоги. В связи с этим еще более важно предусмотреть метод закрытия немодального диалога. При этом, если пользователь находится за пределами диалога, то фокус будет переведен на элемент, открывший диалог, что может быть не самым приятным для пользователя.

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

Закрытие диалога¶

Для закрытия диалога не нужен метод HTMLDialogElement.close() . Вам вообще не нужен JavaScript. Чтобы закрыть без JavaScript, включите форму с диалоговым методом, установив method=»dialog» в или formmethod=»dialog» в кнопке.

Когда пользователь отправляет запрос с помощью метода dialog , состояние введенных пользователем данных сохраняется. Пока происходит событие отправки, форма проходит валидацию ограничений (если не установлено значение novalidate ), данные пользователя не очищаются и не отправляются. Кнопка закрытия без использования JavaScript может быть записана в виде:

1 2 3 4 5
dialog open> form method="dialog"> button type="submit" autofocus>closebutton> form> dialog> 

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

По умолчанию при открытии диалога фокус получает первый фокусируемый элемент внутри диалога, если для другого элемента внутри диалога не установлен атрибут autofocus . Установка атрибута autofocus для кнопки закрытия гарантирует, что она получит фокус при открытии диалога. Однако включать autofocus внутри следует только с большой осторожностью. Все элементы в последовательности, идущие перед элементом с автофокусом, пропускаются. Более подробно этот атрибут рассматривается в уроке по фокусу.

Интерфейс HTMLDialogElement включает свойство returnValue . При отправке формы с помощью method=»dialog» свойство returnValue устанавливается в значение name (если таковое имеется) кнопки отправки, используемой для отправки формы. Если бы мы написали , то returnValue было бы toasty .

При открытии диалога присутствует атрибут boolean open , означающий, что диалог активен и с ним можно взаимодействовать. Если диалог открывается не через .show() или .showModal() , а добавлением атрибута open , то он будет безмодальным. Свойство HTMLDialogElement.open возвращает true или false , в зависимости от того, доступен ли диалог для взаимодействия, а не от того, является он модальным или нет.

Хотя JavaScript является предпочтительным методом открытия диалога, включение атрибута open при загрузке страницы и последующее его удаление с помощью .close() может помочь обеспечить доступность диалога даже при отсутствии JavaScript.

Дополнительные сведения¶

Не используйте tabindex .¶

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

ARIA-роли¶

Неявной ролью является dialog . Если диалог является окном подтверждения, сообщающим о важном сообщении, требующем подтверждения или другой реакции пользователя, установите role=»alertdialog» . Диалог также должен иметь доступное имя. Если видимый текст может обеспечить доступное имя, добавьте aria-labelledby=»idOfLabelingText» .

CSS по умолчанию¶

Обратите внимание, что браузеры предоставляют стили по умолчанию для dialog . Firefox, Chrome и Edge устанавливают color: CanvasText; background-color: Canvas; , а Safari устанавливает color: black; background-color: white; в своих таблицах стилей user-agent. Свойство color наследуется от dialog , а не от body или :root , что может быть неожиданным. Свойство background-color не наследуется.

Модальные и немодальные диалоговые окна

Класс CDialog можно использовать для управления двумя типами диалоговых окон:

  • Модальные диалоговые окна, которые требуют от пользователя ответа перед продолжением программы
  • Бессерверные диалоговые окна, которые остаются на экране и доступны для использования в любое время, но разрешают другие действия пользователя

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

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

  1. С помощью редактора диалогов можно создать диалоговое окно и создать его ресурс шаблона диалогового окна.
  2. Создайте класс диалогов.
  3. Подключение элементы управления ресурса диалогового окна обработчикам сообщений в классе диалогов.
  4. Добавьте элементы данных, связанные с элементами управления диалогового окна, и укажите диалоговые проверки данных и проверки данных диалоговых окон для элементов управления.

См. также

Обратная связь

Были ли сведения на этой странице полезными?

Обратная связь

Coming soon: Throughout 2024 we will be phasing out GitHub Issues as the feedback mechanism for content and replacing it with a new feedback system. For more information see: https://aka.ms/ContentUserFeedback.

Отправить и просмотреть отзыв по

Какая разница между диалоговыми и модальными окнами

Собственно не могу понять, есть ли какая нибудь разница? Или это одно и тоже? В Bootstrap классы элемента модалки вот такие modal-dialog . Я думал Dialog — то что выводится по центру А Modal прилипает к границам вьюпорта

Отслеживать

задан 8 апр 2022 в 13:04

7,054 4 4 золотых знака 30 30 серебряных знаков 64 64 бронзовых знака

В UI модальный диалог не дает взаимодействовать с другими компонентами пока он открыт. А немодальных диалогов может быть несколько одновременно открыто и с ними можно взаимодействовать как и с другими компононентами

Простой способ создания и переиспользования модальных диалогов во Vue 3

image

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

Но что делать, если у вас десятки или даже сотни похожих диалогов на одной странице или даже во всем проекте? Или нужно вызывать диалоги по цепочке в зависимости от выбора пользователя? Как абстрагировать такой функционал и не получить в результате запутанный и плохо поддерживаемый код?

Неплохо было бы создать такую функцию, которая принимала бы компонент диалога и управляла бы его рендерингом в шаблоне, а возвращаемый ею объект содержал бы состояние диалога и методы вызова, чтобы с ним можно было работать как с промисами. Как например в этой библиотеке vue-modal-dialogs. К сожалению она давно не обновлялась и не поддерживает Vue 3.

В этом гайде я представлю вам плагин vuejs-confirm-dialog и покажу как им пользоваться. Начну с простых примеров и закончу созданием функциии полностью абстрагирующей вызов диалога для подтверждения действия, которую можно применять в любом компоненте вашего проекте. Примеры написаны на JavaScript для облегчения восприятия, но сам плагин на TypeScript . Плагин полность типизирован и задокументирован, что значительно облегчает работу с ним. В отличие от vue-modal-dialogs этот плагин имеет дополнительный функционал. Это особые хуки: onConfirm и onCancel . Они принимают колбек и срабатывают в зависимости от решения пользователя: onConfirm если пользователь согласится и onCancel если откажется.

Конечный результат можно посмотреть в песочнице. Код незначительно отличается от того, что в посте.

Установка

Начнем с создания нового проекта на Vue 3. Введем в консоли:

vue create dialogs-guide // Pick a second option ? Please pick a preset: Default ([Vue 2] babel, eslint) > Default (Vue 3) ([Vue 3] babel, eslint) Manually select features

Мы получили стандартный шаблон нового проекта. Далее перейдем в папку проекта и установим плагин согласно документации в README.md.

npm i vuejs-confirm-dialog

Заменим код в main.js на такой:

import < createApp >from 'vue' import App from './App.vue' import * as ConfirmDialog from 'vuejs-confirm-dialog' createApp(App).use(ConfirmDialog).mount('#app')

Использование

Теперь перейдем в файл App.vue. Первым делом исправим код шаблона. Для работы библиотеки нам обязательно нужно добавить в него компонент и удалим HelloWord :

 

Теперь изучим как использовать функцию createConfirmDialog . Используем новый синтаксис setup для раздела script . createConfirmDialog первым аргументом принимает компонент, который будет использоваться как модальное окно, а вторым входные данные для него. Функция возвращает обьект с методами для работы с модальным окном, так метод reveal вызывает диалог, а хук onConfirm принимает код, который выполняется если пользователь нажмет на «согласен». Можно заставить появляться компонент HelloWord при нажатии на лого и передать ему значение пропса msg :

// App.vue   

Никакой дополнительной логики не требуется. Компонент отрисовывается после вызова функции reveal и исчезает после того, как пользователь отреагирует на диалог.

Реалистичный пример компонента

Теперь напишем что-то более приближенное к реальному использованию.

Создадим новый компонент SimpleDialog.vue в папке components :

   .modal-container < display: flex; justify-content: center; align-items: center; position: absolute; top: 0; left: 0; right: 0; width: 100%; height: 100%; background-color: #cececeb5; >.modal-body < background-color: #fff; border: 2px solid #74a2cf; border-radius: 10px; text-align: center; padding: 20px 40px; min-width: 250px; display: flex; flex-direction: column; >.modal-action < display: flex; flex-direction: row; gap: 40px; justify-content: center; >.modal-button < cursor: pointer; height: 30px; padding: 0 25px; border: 2px solid #74a2cf; border-radius: 5px; background-color: #80b2e4; color: #fff; >.modal-close 

Обратите внимание, что для полноценной работы нужно добавить два входящих события в модальный диалог: [‘confirm’, ‘cancel’] .

А теперь используем его для подтверждения какого-либо действия, например, чтобы спрятать лого. Логику кода, который будет исполняться после согласия пользователя, поместим в коллбек хука onConfirm .

   

Переиспользование

Что делать, если у нас есть много случаев, когда требуется подтверждение каких-либо действий? Не писать же каждый раз createConfirmDialog заново?

Можно написать функцию, которая автоматизирует этот процесс для нас.

// src/composables/useConfirmBeforeAction.js import SimpleDialog from './../components/SimpleDialog' import < createConfirmDialog >from 'vuejs-confirm-dialog' const useConfirmBeforeAction = (action, props) => < const < reveal, onConfirm >= createConfirmDialog(SimpleDialog, props) onConfirm(action) reveal() > export default useConfirmBeforeAction

Теперь используем ее для подтверждения перехода по внешним ссылкам:

Заключение

Функция createConfirmDialog позволяет упростить работу с модальными окнами, переиспользование логики и создание цепочек последовательных диалогов. Она берет на себе заботу о рендере модального окна, передачу входящих параметров в компонент и получении данных от него. Она очень гибкая — ее очень легко подстроить под ваши нужды.

Это не все ее возможности. Например, если концеция хуков вам не близка, можно заменить их на работу с промисом, который возвращает reveal . И даже использовать её в Options API, если вас не отпускает ностальгия по Vue 2.

  • Веб-разработка
  • JavaScript
  • Программирование
  • VueJS

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *