如何使 v-menu 键盘可访问
How to make v-menu keyboard accessible
Vuetify 5.10 和 Vue 2.6.14。
我知道 Vuetify 文档说:
By default, v-menu components are detached and moved to the root of your application. In order to properly support inserting dynamic content into the DOM, you must use the attach prop. This will ensure that focus transfers from the activator to the content when pressing the tab key.
但他们没有提供任何示例,我试过了,但我无法让它工作,所以我最终没有使用它,只是有一种方法可以在点击时显示和隐藏我的下拉菜单(它可以工作,但它听起来可能 v-menu).
这是我试过的方法,无法通过键盘访问:
<v-menu>
<template v-slot:activator="{ on, attrs }"> -->
<div v-bind="attrs" v-on="on" class="nearby-trigger">
<toggle-button
phrase="Location"
standalone
attach="#nearbyLocation"
></toggle-button>
</div>
</template>
<v-card id="nearbyLocation">
<v-container>
<v-row>
<v-col>
<v-text-field hide-details placeholder="Area Code"></v-text-field>
</v-col>
</v-row>
</v-container>
</v-card>
</v-menu>
更新:
要对该问题进行更多解释:
问题是 v-menu 在 DOM 树的末尾注入了所有内容所以假设我有一个 header 和我的 v-menu 然后是 main 然后是页脚,我可以在页脚之后通过键盘访问该菜单,所以我必须一直跳到页脚之后。总之,它出现在正确的位置但不符合正确的 Tab 键顺序(是的,我试过 tabindex)
感谢您的帮助!
当使用 Tab 键到达 v-menu 按钮并使用箭头键在项目之间导航时,这个沙盒示例似乎有效:
<template>
<div class="text-xs-center">
<v-menu offset-y>
<template v-slot:activator="{ on }">
<v-btn color="primary" dark v-on="on" id="menuButton"> Dropdown </v-btn>
</template>
<v-list>
<v-list-tile
v-for="(item, index) in items"
:key="index"
@click="onMenuItemClick(item)"
tabindex="1"
>
<v-list-tile-title>{{ item.title }}</v-list-tile-title>
</v-list-tile>
</v-list>
</v-menu>
</div>
</template>
<script>
export default {
data: () => ({
items: [
{ title: "List Item 1" },
{ title: "List Item 2" },
{ title: "List Item 3" },
{ title: "List Item 4" },
],
menuButton: undefined,
}),
methods: {
onMenuItemClick(item) {
console.log(`${item.title} clicked`);
// manually set focus back to the button on click.
this.menuButton.focus();
},
},
mounted() {
this.menuButton = document.getElementById("menuButton");
},
};
</script>
https://codesandbox.io/s/vuetify-sandbox-32bw5r?file=/src/components/Menu.vue
感谢@dick.ey帮助我回答这个问题
解决办法是找出附件。默认情况下 v-menu 附加在根 (https://github.com/vuetifyjs/vuetify/blob/master/packages/vuetify/src/components/VMenu/VMenu.ts)
您可以将 v-menu 附加到特定位置,该位置将成为 v-menu 所在位置的父位置。因为我不想打扰订单或 css 我选择创建一个 div 父容器并将其附加到它。
<div id="searchMenu">
<v-menu attach="#searchMenu">
<template v-slot:activator="{ on, attrs }"> -->
<div v-bind="attrs" v-on="on" class="nearby-trigger">
<toggle-button
phrase="Location"
standalone
attach="#nearbyLocation"
></toggle-button>
</div>
</template>
<v-card id="nearbyLocation">
<v-container>
<v-row>
<v-col>
<v-text-field hide-details placeholder="Area Code"></v-text-field>
</v-col>
</v-row>
</v-container>
</v-card>
</v-menu>
</div>
该代码中的 div 将始终存在,而我的卡片现在被添加到该 div 的末尾,而不是我的根目录的末尾,后者将包含一个页脚,这对键盘辅助功能。
Vuetify 5.10 和 Vue 2.6.14。
我知道 Vuetify 文档说:
By default, v-menu components are detached and moved to the root of your application. In order to properly support inserting dynamic content into the DOM, you must use the attach prop. This will ensure that focus transfers from the activator to the content when pressing the tab key.
但他们没有提供任何示例,我试过了,但我无法让它工作,所以我最终没有使用它,只是有一种方法可以在点击时显示和隐藏我的下拉菜单(它可以工作,但它听起来可能 v-menu).
这是我试过的方法,无法通过键盘访问:
<v-menu>
<template v-slot:activator="{ on, attrs }"> -->
<div v-bind="attrs" v-on="on" class="nearby-trigger">
<toggle-button
phrase="Location"
standalone
attach="#nearbyLocation"
></toggle-button>
</div>
</template>
<v-card id="nearbyLocation">
<v-container>
<v-row>
<v-col>
<v-text-field hide-details placeholder="Area Code"></v-text-field>
</v-col>
</v-row>
</v-container>
</v-card>
</v-menu>
更新: 要对该问题进行更多解释: 问题是 v-menu 在 DOM 树的末尾注入了所有内容所以假设我有一个 header 和我的 v-menu 然后是 main 然后是页脚,我可以在页脚之后通过键盘访问该菜单,所以我必须一直跳到页脚之后。总之,它出现在正确的位置但不符合正确的 Tab 键顺序(是的,我试过 tabindex)
感谢您的帮助!
当使用 Tab 键到达 v-menu 按钮并使用箭头键在项目之间导航时,这个沙盒示例似乎有效:
<template>
<div class="text-xs-center">
<v-menu offset-y>
<template v-slot:activator="{ on }">
<v-btn color="primary" dark v-on="on" id="menuButton"> Dropdown </v-btn>
</template>
<v-list>
<v-list-tile
v-for="(item, index) in items"
:key="index"
@click="onMenuItemClick(item)"
tabindex="1"
>
<v-list-tile-title>{{ item.title }}</v-list-tile-title>
</v-list-tile>
</v-list>
</v-menu>
</div>
</template>
<script>
export default {
data: () => ({
items: [
{ title: "List Item 1" },
{ title: "List Item 2" },
{ title: "List Item 3" },
{ title: "List Item 4" },
],
menuButton: undefined,
}),
methods: {
onMenuItemClick(item) {
console.log(`${item.title} clicked`);
// manually set focus back to the button on click.
this.menuButton.focus();
},
},
mounted() {
this.menuButton = document.getElementById("menuButton");
},
};
</script>
https://codesandbox.io/s/vuetify-sandbox-32bw5r?file=/src/components/Menu.vue
感谢@dick.ey帮助我回答这个问题
解决办法是找出附件。默认情况下 v-menu 附加在根 (https://github.com/vuetifyjs/vuetify/blob/master/packages/vuetify/src/components/VMenu/VMenu.ts)
您可以将 v-menu 附加到特定位置,该位置将成为 v-menu 所在位置的父位置。因为我不想打扰订单或 css 我选择创建一个 div 父容器并将其附加到它。
<div id="searchMenu">
<v-menu attach="#searchMenu">
<template v-slot:activator="{ on, attrs }"> -->
<div v-bind="attrs" v-on="on" class="nearby-trigger">
<toggle-button
phrase="Location"
standalone
attach="#nearbyLocation"
></toggle-button>
</div>
</template>
<v-card id="nearbyLocation">
<v-container>
<v-row>
<v-col>
<v-text-field hide-details placeholder="Area Code"></v-text-field>
</v-col>
</v-row>
</v-container>
</v-card>
</v-menu>
</div>
该代码中的 div 将始终存在,而我的卡片现在被添加到该 div 的末尾,而不是我的根目录的末尾,后者将包含一个页脚,这对键盘辅助功能。