使用HTML对话框元素进行对话框
#html #网络开发人员 #a11y #tutorials

对话框和模式是任何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的动作按钮,例如取消和确认按钮。

我们对话框的示例草图如下:

Sketch design of dialog element divided into three sections of header, content and footer actions

现在,让我们在HTML文件的body部分中添加一个带有上述部分的dialog标记元素。 dialog具有带有值main-dialogid属性,如下所示:

<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 ”将onclickonclick事件绑定,使用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();
})

刷新浏览器,您现在可以看到对话框在单击打开对话框按钮时打开。

Demo on how to open dialog using a button

对话框打开后,我们应该将其他菜单按钮和标头按钮绑定到适当的事件处理程序,并相应地使用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())

我们现在使组件完全可行。

Full flow demo on opening dialog and closing dialog by clicking on dialog buttons

可访问性呢? dialog是否提供任何可访问性支持?让我们找出下一步。

使用dialog的可访问性

可访问的对话框需要以下特征:

  • 使用键盘导航打开对话框时,浏览器应在对话框中的第一个按钮上自动对焦。在我们的情况下,这是对话框标题处的关闭按钮。
  • 关闭对话框后,浏览器应恢复我们用来打开对话框的按钮上的焦点,从而使用户可以恢复其导航流。
  • 屏幕读取器应该能够宣布对话框的标签,并且在输入对话框时可选。

要将重点放在对话框中的第一个可见按钮上,我们使用对话框的autofocus属性。对于其标签和描述,我们可以分别将WAI ARIA属性aria-labelledbyaria-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关键事件!

以下是对话框元素的导航键盘和焦点的样子的演示:

Demo on how dialog works when using Tab key navigation

注意

如果您想以编程方式添加动画效果,请注意,您将 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元素创建了第一个对话框。

演示

演示代码可用于尝试。 ð

Experimenting HTML dialog element

浏览器支持

all major browsers except Internet Explorer中对dialog及其API有全力支持。现在,我们可以享受内置对话元素的好处,并开始根据我们的需求进行自定义。太棒了,不是吗?


概括

在这篇文章中,我们经历了使用HTML和DOM API构建对话框组件的基础知识。使用dialog元素,在前端框架中组成可重复使用的对话框组件变得更加简单。您也可以使用相同的方法来创建模式或吐司通知组件。

接下来,尝试在您喜欢的框架中制作对话框组件,例如VUE或使用dialog元素进行反应?应该很有趣ð!

ð如果您想赶上我有时候,请在Twitter上关注我| Facebook

ð通过我的新书Learning Vue了解Vue。早期版本现在可以使用!

喜欢这篇文章还是发现它有帮助?分享ðð¼ð