焦点元素的选择
通常,我们可以使用Tab键和Shift+Tab键,来进行焦点元素的选择。除了浏览器默认提供的input、button之类的元素,你也可以给其他元素添加tabindex属性,使其成为焦点元素,如下面的div元素,我们给它添加了tabindex属性,使其成为焦点元素,从而可以通过tab键来聚焦到它上面,再通过enter键来触发它的点击事件
<div id="test001" tabindex="0">点一下这个div</div>
聚焦时的样式
使用focus伪类选择器,可以设置元素在被聚焦时的样式,如下面的button元素
button{
outline: 4px solid red;
}
通常情况下,对于组件化开发,我们通常会将可交互的元素进一步封装成组件,而此时我们希望focus样式凸显出来的不是一个单独的交互元素,而是整个组件本身,这时候就需要使用:focus-within伪类选择器,它可以选择到当前元素或其子元素处于focus的状态,比如,博客的导航栏,当聚焦到导航栏的子元素a时,导航栏就会被选中,从而展示子导航栏(可尝试使用tab或shift+tab聚焦到导航栏体验)
/* 当menu-items内部的menu-item被tab选中聚焦时,父容器就会显现 */
.menu-trigger .menu-items:focus-within {
display: block;
}
这个伪类将聚焦元素焦点的来源进行了区分,只会在通过键盘聚焦到此元素的时候才会被此伪类选中,通过鼠标点击触发的聚焦则不会被选中。
#test002:focus {
outline: 4px solid green;
}
#test002:focus-visible {
outline: 4px solid red;
}
使用这个伪类,就可以之将聚焦样式绑定到键盘交互上面,对于鼠标交互,则另外通过hover进行相应实现。
聚焦时的行为
默认情况下,enter键和space空格键会触发焦点元素的click点击事件。在自定义组件中,我们可以通过监听click或者keydown事件,来实现自定义操作,如打开弹窗、侧边栏等。不过需要注意的是,由于我们通过自定义操作打开了新的组件,所以我们需要在监听回调中实现焦点元素的转移,即聚焦到新打开的组件中(escape也是一样,退出组件后,需要将焦点还给触发元素)
可使用tab键聚焦到我博客导航栏中的搜索键或面板键,enter打开,escape退出,体验一下
// 打开弹窗
triggerElement.addEventListener('keydown', (e) => {
if (e.key === 'Enter') {
// 打开弹窗
// ...
// 聚焦到弹窗元素
modalElement中某个可聚焦元素.focus();
}
})
// 退出弹窗
modalElement.addEventListener('keydown', (e) => {
if (e.key === 'Escape') {
// 关闭弹窗
// ...
// 聚焦到触发弹窗的元素
triggerElement.focus();
}
})
通常,使用方向键和空格,可以进行表单项的选择
Apple Orange Banana
1 2
上述为一些常用表单元素,可尝试,一般我喜欢使用radio来设计组件(因为它可以使用方向键进行选择),比如下面的tabs组件,可以使用方向键切换tab
其实常用的交互按键,就是上面的tab、shift+tab、enter、escape、空格,而方向键则是用于操作焦点元素,如单选框、复选框等,还有就是页面滚动。这里就不再赘述了。 对于其他按键,你可以在自定义组件中通过监听事件来实现更多功能(比如我这里有一个代办计划就是,当聚焦到某个元素身上的时候,通过Capslock键来唤起相应的右键菜单(全局右键菜单,然后读取组件实现的特定接口,来展示相应的右键菜单))