处理用户互动
专家模式关闭
专家模式
使用专家模式隐藏面向初学者的 Web 开发指导。
构建菜单
用户需要一种方法来浏览包含许多页面的网站。在许多网站和应用程序中,您可能已经看到,这是通过导航菜单实现的。我们产品经理对菜单的要求如下
-
用户通过单击页面顶部的图标(
☰
)打开菜单。 -
菜单打开后,可以通过单击菜单外部或单击菜单右上角的
X
图标将其关闭。 -
菜单应包含多个链接,单击这些链接可导航到其他页面。
从 AMP 组件的列表中,我们决定使用以下组件
-
菜单将使用
<amp-sidebar>
实现。 -
☰
和X
图标将实现为<div>
标记,单击这些标记时会打开菜单。 -
页面链接的集合将实现为锚标记的无序列表(
<ul>
、<li>
和<a>
标记)。
仍然存在一些问题。例如,我们如何检测用户何时单击图标以打开或关闭菜单?或者,我们如何打开 <amp-sidebar>
组件?
我们需要了解如何在 AMP 中检测用户输入,以及如何响应这些用户输入执行操作。
用户互动和事件简介
想想与网站互动的所有方式。这包括单击鼠标、在触摸屏上点击手指或使用键盘键入。单击按钮可能会将我们所有的电子邮件标记为已读,或者可能会打开菜单。按下键盘上的 Escape 键可能会关闭弹出窗口。用手指向右滑动可能会接受任务或与另一个用户建立连接。
当用户以任何这些方式与我们网站上的元素进行交互时,会触发一个事件。事件为我们网站上的元素和组件提供了一种方式来告诉我们刚刚发生了一些重要的事情。
在 AMP 中,我们可以选择对我们重要的事件,并通过将 on
属性与 HTML 标记和 AMP 组件一起使用来“处理”它们,以表示我们希望对交互做出反应。当用户执行上述操作时,会在受影响的组件上触发“事件”。响应于该事件,将执行 on
属性中指定的“操作”。
例如,假设有一个按钮可以使屏幕上的消息消失。在 AMP 中,当用户单击该按钮时,会触发 tap
事件。如果该事件包含在该按钮的 on
属性中,则会运行事件处理程序,从而隐藏警告消息。
此事件序列可以在经典 HTML 中实现,如下所示
<div id="warning">This is a warning.</div> <button onclick="document.getElementById(‘warning’).hidden = true;"> Hide Warning </button>
如果您曾经使用过 jQuery,则等效的将是以下代码
<div id="warning">This is a warning.</div> <button onclick="$('#warning').hide();"> Hide Warning </button>
同时,在 AMP 中,它看起来像这样
<div id="warning">This is a warning.</div> <button on="tap:warning.hide"> Hide Warning </button>
在上面的 on
属性中,我们看到 tap:warning.hide
。在这种情况下,tap
是事件,warning
是要操作的元素的 ID,而 hide
是要执行的操作。请注意,hide
是每个 AMP 组件甚至其他 HTML 元素上可用的通用操作之一。AMP 组件的文档通常包含可以在该组件上执行的操作列表。
某些操作采用函数的形式,并且可以接受参数。在其他情况下,如果操作很明显,则可以完全省略操作。在每种情况下,都可以在该组件的文档中找到详细信息。在本课程的后面,我们将看到这些类型操作的示例。
练习 1:构建菜单
现在是时候使用 <amp-sidebar>
组件在我们的网站中实现导航菜单了。<amp-sidebar>
是一个最初隐藏在屏幕外的面板。打开侧边栏时,内容面板将滑动到视图中。通过在组件上调用一个操作来打开侧边栏。它可以在屏幕的右侧或左侧打开。组件显示在哪个侧面由 side
属性控制(默认值为 left
)。侧边栏将保持在屏幕上,直到通过操作将其关闭,或者直到用户单击组件外部。
可以使用以下操作打开 ID 为 sidebar1
的侧边栏
-
sidebar1.open
-
sidebar1.toggle
-
sidebar1
打开后,可以使用以下操作关闭 ID 为 sidebar1
的侧边栏
-
sidebar1.close
-
sidebar1.toggle
现在,使用<amp-sidebar>
的文档以及AMP 事件和操作列表,添加一个符合以下规范的导航菜单
-
在页面的
<header>
元素中,添加一个<div>
,其中包含文本图标 ☰,该图标在点击时会切换侧边栏。 -
添加一个
<amp-sidebar>
组件,其id
为sidebar1
,该组件显示在屏幕的左侧。 -
向菜单添加四个列表项,这些项暂时都链接到
#
(这是一个无处可去的链接,但我们将在将来的步骤中添加实际 URL):我们的故事、我们的自行车、最新型号和联系方式。 -
我们需要创建一个按钮来打开菜单,另一个按钮来关闭菜单。在侧边栏的顶部,添加一个包含 X 的
<div>
,该 X 会切换侧边栏。 -
用
<nav>
HTML 元素包围侧边栏中的链接列表。 -
将链接列表实现为包含列表项(
<li>
)的无序列表(<ul>
),该列表项包含锚链接(<a>
)。
推荐的 CSS 指南
-
为
<amp-sidebar>
指定一个类sidebar
。 -
为
nav
元素指定一个类nav
。 -
为
ul
元素指定一个类label
。 -
为
li
元素指定一个类nav-item
。
完成后,您的页面在菜单滑出之前和之后应如下所示
解决方案
包含侧边栏的页面部分应如下所示
<header class="headerbar"> <div class="navbar-trigger" role="button" tabindex="0" on="tap:sidebar1.toggle">☰</div> <h2>Chico's Cheese Bicycles</h2> </header> <amp-sidebar class="sidebar" id="sidebar1" layout="nodisplay" side="left"> <div class="navbar-trigger" role="button" tabindex="0" on="tap:sidebar1.toggle">X</div> <nav class="nav"> <ul class="label"> <li class="nav-item"> <a href="#">Our Story</a> </li> <li class="nav-item"> <a href="#">Our Bikes</a> </li> <li class="nav-item"> <a href="#">Latest Models</a> </li> <li class="nav-item"> <a href="#">Contact</a> </li> </ul> </nav> </amp-sidebar>
此外,请记住在 <head>
中包含 <amp-sidebar>
JavaScript
<script async custom-element="amp-sidebar" src="https://cdn.ampproject.org/v0/amp-sidebar-0.1.js"></script>
辅助功能
在制作侧边栏时,您是否检查了 AMP 验证器?在您工作时,您可能收到了如下错误消息
此处出现两个不同的错误,对于我们附加了 on
属性的每个可单击元素都会重复出现。但是为什么呢?
请记住,AMP 在 Web 上强制执行最佳实践。在这种情况下,AMP 正在确保您的页面可以供使用辅助技术(例如屏幕阅读器)的用户访问。
让我们看看第一个
The attribute 'role' in tag ‘div' is missing or incorrect, but required by attribute 'on'.
在此示例中,我们添加了一个充当按钮的 <div>
元素。也就是说,<div>
是可单击的,并且在单击时会触发“事件”。某些残疾人士需要辅助技术(例如屏幕阅读器)来浏览 Web。屏幕阅读器需要知道哪些元素的行为类似于按钮,以便它可以将该事实传达给用户。如果您的元素是可单击的,则必须告知屏幕阅读器。因此,要消除错误,您必须在可单击的 <div>
中添加 role="button"
属性。
现在是第二个错误
The attribute 'tabindex' in tag 'div' is missing or incorrect, but required by attribute 'on'.
我们的一些 <div>
充当按钮。按钮允许用户交互,以便 AMP 知道它们是可聚焦的。“可聚焦”意味着,如果用户仅使用键盘浏览您的网页,则他们可以突出显示可聚焦组件并与之交互。在这种情况下,解决方案是向切换侧边栏的 <div>
添加一个 tabindex
,以便用户可以使用键盘访问该元素。
练习 2:向侧边栏添加子菜单
哎呀!我们的产品经理打电话来说,市场团队要求在网站菜单中展示的奶酪自行车种类太多,无法在一个单独的列表中显示。(毕竟,我们最近在产品库存中添加了软奶酪。)经理建议最好将额外的部分组织成子菜单。点击节标题会展开相应的子菜单,显示嵌套的链接。再次点击节标题会关闭子菜单,隐藏所有包含的链接。
<amp-sidebar>
的文档没有说明如何实现嵌套子菜单。我们需要找到另一个可以与 <amp-sidebar>
结合使用的组件,以便为我们的侧边栏添加可折叠子菜单。
如果我们去 Google 搜索“ui 可折叠内容”,我们会看到一些关于如何构建“手风琴”的搜索结果。在浏览结果后,我们意识到手风琴正是我们所需要的。但是 AMP 是否提供了可以作为手风琴的组件呢?
浏览 AMP 组件的列表,在布局部分,我们发现确实有一个 <amp-accordion>
组件符合我们的需求。
我们可以将 <amp-accordion>
组件放置在 <amp-sidebar>
组件内部,就像我们在上一个练习中将 <ul>
、<li>
和 <a>
标签放置在 <amp-sidebar>
内部一样。当菜单打开时,手风琴组件将以其默认的折叠状态显示。然后,可以通过与它们交互来展开或关闭手风琴。当菜单关闭时,手风琴将与菜单中的所有其他内容一起消失。通过 <amp-sidebar>
和 <amp-accordion>
的协同工作,我们可以创建一个滑出式嵌套导航菜单!
<amp-img>
组件放置在 <amp-carousel>
组件内部来创建我们的第一个图像轮播吗?将组件放置在其他组件内部是它们可以有效协同工作的一种方式。我们将在本课程的后面部分介绍其他组合组件的方法。使用 <amp-accordion>
的文档,增强您的侧边栏导航,添加具有以下规范的子菜单
-
将
<amp-sidebar>
中的“我们的自行车”列表项转换为一个可展开的列表,其中包含 Chico's Cheese Bicycles 的可用自行车:Ricotta Racer、Cheddar Chase 和 Parmesan Pacer。 -
将
<amp-sidebar>
中的“最新型号”列表项转换为一个可展开的列表,其中包含 Chico's Cheese Bicycles 的最新型号:臭名昭著的 Ricotta Racer。
推荐的样式指南
-
将
nav-dropdown
类添加到包含可展开列表的<li>
中。 -
将
dropdown
类添加到您添加的每个<amp-accordion>
中。 -
将
dropdown-item
类添加到每个嵌套列表<li>
元素中,并将dropdown-items
类添加到嵌套的<ul>
元素中。 -
为您添加的
<amp-accordion>
提供container
的layout
。
完成后,您展开的侧边菜单应如下所示
解决方案
<amp-sidebar class="sidebar" id="sidebar1" layout="nodisplay" side="left"> <div class="navbar-trigger" on="tap:sidebar1.toggle">X</div> <nav class="nav"> <ul class="label"> <li class="nav-item"> <a href="#">Our Story</a> </li> <li class="nav-item nav-dropdown"> <amp-accordion layout="container" disable-session-states class="dropdown"> <section> <header>Our Bikes</header> <ul class="dropdown-items"> <li class="dropdown-item"> <a href="#">Ricotta Racer</a> </li> <li class="dropdown-item"> <a href="#">Cheddar Chaser</a> </li> <li class="dropdown-item"> <a href="#">Parmesan Pacer</a> </li> </ul> </section> </amp-accordion> </li> <li class="nav-item nav-dropdown"> <amp-accordion layout="container" disable-session-states class="dropdown"> <section> <header>Latest Models</header> <ul class="dropdown-items"> <li class="dropdown-item"> <a href="#">Ricotta Racer</a> </li> </ul> </section> </amp-accordion> </li> <li class="nav-item"> <a href="#">Contact</a> </li> </ul> </nav> </amp-sidebar>
请记住在 <head>
中包含 <amp-accordion>
JavaScript
<script async custom-element="amp-accordion" src="https://cdn.ampproject.org/v0/amp-accordion-0.1.js"></script>