对话框和模式是任何Web应用程序的重要组件。尽管如此,我们仍需要使用现有的div
元素来创建和定义默认行为逻辑。但是有了dialog
元素,事情可能会更容易。让我们在这篇文章中检查一下吗?
介绍dialog
元素
对话框元素dialog
是一个非常新的HTML5元素,您可以将其与<dialog>
标记一起使用,如下示例所示:
<dialog>
<div>
I'm a dialog!
</div>
</dialog>
与其他HTML5元素不同,dialog
元素带有内置API和一些基本CSS样式。根据设计,dialog
元素具有两个状态-em 可见(open)或 hidden (关闭),由单个属性open
:
表示
<dialog open>
<div>
This dialog is opened and visible!
</div>
</dialog>
<dialog>
<div>
This dialog is hidden!
</div>
</dialog>
dialog
的初始状态为“ hidden ”。 dialog
元素公开了以下API方法来控制其条件:
-
showModal()
-通过将属性open
设置为元素来打开对话框。它还添加了一个::backdrop
伪元素,以覆盖元素外部的内容作为覆盖效果。 -
show()
-类似于showModal
,但没有添加背景。此方法可用于将dialog
用作吐司通知。 -
close(newReturnValue)
-通过删除open
属性来关闭对话框,并在dialog
元素的returnValue
上更新dialog
element。
使用上面给定的API,让我们接下来实现一个简单的对话框。
创建一个简单的对话框
我们将创建一个包含三个部分的简单对话框:
-
header
,具有对话框标题和一个取消按钮(带有X指示器) -
main
部分,在其中显示对话框的所有内容。在我们的示例中,这只是一个简单的字符串。 -
footer
包含一个menu
的动作按钮,例如取消和确认按钮。
我们对话框的示例草图如下:
现在,让我们在HTML
文件的body
部分中添加一个带有上述部分的dialog
标记元素。 dialog
具有带有值main-dialog
的id
属性,如下所示:
<html>
<body>
<dialog id="main-dialog">
<header>
<h2>Dialog header</h2>
<button id="cancel-btn">X</button>
</header>
<main>
Dialog content
</main>
<footer>
<menu>
<button id="cancel-btn">Cancel</button>
<button id="confirm-btn">Confirm</button>
</menu>
</footer>
</dialog>
</body>
</html>
接下来,我们添加到body
一个main
元素,该元素包含一个button
打开对话框:
<body>
<main id="app">
<button id="open-dialog-btn">Open dialog</button>
</main>
<dialog id="main-dialog">
<!--....-->
</dialog>
</body>
在浏览器上运行上述代码时,您不会看到对话框,因为默认情况下不可见。我们需要使用id
“ open-dialog-btn ”将onclick
的onclick
事件绑定,使用addEventListener
方法如下:
//1. Query for open dialog button
const openBtn = document.getElementById('open-dialog-btn');
//2. Query for dialog element
const dialog = document.getElementById('main-dialog');
//3. Add event listener to open dialog on click
openBtn.addEventListener('click', () => {
dialog.showModal();
})
刷新浏览器,您现在可以看到对话框在单击打开对话框按钮时打开。
对话框打开后,我们应该将其他菜单按钮和标头按钮绑定到适当的事件处理程序,并相应地使用dialog.close()
关闭对话框。
//1. Query for the buttons
const cancelBtn = document.getElementById('cancel-btn');
const confirmBtn = document.getElementById('confirm-btn');
const headerCancelBtn = document.getElementById('cancel-btn');
//2. Bind to onclick event
cancelBtn.addEventListener('click', () => dialog.close());
confirmBtn.addEventListener('click', () => dialog.close());
headerCancelBtn.addEventListener('click', () => dialog.close())
我们现在使组件完全可行。
可访问性呢? dialog
是否提供任何可访问性支持?让我们找出下一步。
使用dialog
的可访问性
可访问的对话框需要以下特征:
- 使用键盘导航打开对话框时,浏览器应在对话框中的第一个按钮上自动对焦。在我们的情况下,这是对话框标题处的关闭按钮。
- 关闭对话框后,浏览器应恢复我们用来打开对话框的按钮上的焦点,从而使用户可以恢复其导航流。
- 屏幕读取器应该能够宣布对话框的标签,并且在输入对话框时可选。
要将重点放在对话框中的第一个可见按钮上,我们使用对话框的autofocus
属性。对于其标签和描述,我们可以分别将WAI ARIA属性aria-labelledby
和aria-describedby
分别为目标元素的ID选择器。我们还添加了role="dialog"
(或role="alert"
),以供屏幕读取器正确宣布对话框,如下所示:
:
<dialog
id="main-dialog"
autofocus
role="dialog"
aria-describedby="content-area"
aria-labelledby="label-area"
>
<header>
<h2 id="label-area">Dialog header</h2>
<button id="dialog-header--cancel-btn">X</button>
</header>
<main id="content-area">
Dialog content
</main>
<!-- ... -->
</dialog>
使用dialog
元素的一件好事是,当用户关闭对话框时,浏览器会自动恢复我们用来打开它的按钮上的焦点。这也适用于ESC关键事件!
以下是对话框元素的导航键盘和焦点的样子的演示:
注意
如果您想以编程方式添加动画效果,请注意,您将 Lose 此内置功能支持,并且必须自己实现Tab Navigation focus。
到目前为止,太好了吗?接下来,我们将查看如何使用内部对话框。
在对话框中使用表格
dialog
元素为form
提供了内置支持。为了启用对话框及其嵌套形式之间的连接,我们将form
元素的method
属性设置为dialog
。然后,我们将原始内容包装在form
元素中,如下所示:
<dialog
id="main-dialog"
autofocus
<!--...-->
>
<form method='dialog'>
<!--The rest of the code -->
</form>
</dialog>
这样做,触发任何表单的按钮元素(除了使用type='reset"
的按钮)也将自动关闭对话框,而不是手动绑定每个对话框的功能。
现在,我们可以删除所有用于关闭对话框的OnClick事件听众,并且应该与以前的功能相同。
酷,对吗?如果您想在对话框外部关闭对话框时触发其他逻辑,该怎么办?为此,我们使用close
事件听众。
聆听对话框的close
事件
dialog
有一个close
事件,我们可以将事件处理程序附加到使用以下语法:
dialog.addEventListener('close', () => {
//your handler logic
})
每当用户关闭对话框时,它将触发此处理程序。然后,我们可以在按钮中使用value
属性,并使用dialog.returnValue
访问它们,以确定用户是单击取消按钮还是提交按钮,如下所示:
<menu>
<button id="dialog-footer--cancel-btn" value="cancel">Cancel</button>
<button id="dialog-footer--cancel-btn" value="confirm">Confirm</button>
</menu>
在close
事件侦听器逻辑中,我们可以执行一个简单的条件逻辑:
dialog.addEventListener('close', () => {
if (dialog.returnValue === 'cancel') {
//do something
} else if (dialog.returnValue === 'confirm) {
//do something
}
})
注意在这里,如果用户击中ESC键,则returnValue
不会有任何值。
就是这样!我们使用dialog
元素创建了第一个对话框。
演示
演示代码可用于尝试。 ð
浏览器支持
在all major browsers except Internet Explorer中对dialog
及其API有全力支持。现在,我们可以享受内置对话元素的好处,并开始根据我们的需求进行自定义。太棒了,不是吗?
概括
在这篇文章中,我们经历了使用HTML和DOM API构建对话框组件的基础知识。使用dialog
元素,在前端框架中组成可重复使用的对话框组件变得更加简单。您也可以使用相同的方法来创建模式或吐司通知组件。
接下来,尝试在您喜欢的框架中制作对话框组件,例如VUE或使用dialog
元素进行反应?应该很有趣ð!
ð如果您想赶上我有时候,请在Twitter上关注我| Facebook。
ð通过我的新书Learning Vue了解Vue。早期版本现在可以使用!
喜欢这篇文章还是发现它有帮助?分享ðð¼ð