MDC菜单 - 当焦点在输入框上时保持菜单打开

3

我正在使用mdc web组件搭建一个自动完成输入框。我有一个输入文本框和一个菜单。您可以在这里看到代码沙箱。 我在focusin事件上显示菜单,但如果我开始在输入字段中编写文本,菜单会立即关闭。

const input = new MDCTextField(document.querySelector(".mdc-text-field"));
const menu = new MDCMenu(document.querySelector(".mdc-menu"));

input.listen("focusin", () => (menu.open = true));

我假设这是由于菜单的默认行为在触发菜单外部点击时关闭。问题在于第一个菜单项从文本字段获取了焦点。有什么方法可以防止这种情况发生,并让菜单一直打开,直到输入字段失去焦点?
1个回答

3
这里的问题与可访问性有关,下面是具体步骤:
  1. 当您点击输入框时,输入框会获得“焦点”。

  2. 这会触发“focusin”事件,从而打开菜单。

  3. 然后,根据这里定义的辅助功能文档,MDCMenu将自动将焦点集中在第一个菜单项上。

为了阻止自动进行此焦点集中操作,我们可以设置:

menu.setDefaultFocusState(DefaultFocusState.NONE);

DefaultFocusState.NONE

不改变焦点。如果您不希望菜单在打开时抓取焦点(例如自动完成下拉菜单),请设置为此选项。

如果问题仅限于上述内容,那么这很好解决,但现在的问题是,如果 MDCMenu 失去焦点时会自动关闭。

[编辑]: 下一部分是错误的,锚定并不会使其保持打开状态,只是将其固定在元素周围

要解决这个问题,我们需要将 MDCMenu 锚定到输入元素(必须是原生元素):

menu.setAnchorElement(document.querySelector(".mdc-text-field"));

最后,我们需要告诉 MDCMenu 在焦点从输入框移开后关闭:

input.listen("focusout", () => {
  menu.open = false;
});

可能还有其他问题需要调整,但我认为这些应该可以让你接近目标。 这里有一个共享的代码示例,它也使用了MDCMenu来创建“自动完成下拉菜单”,你可以在这里参考:https://gist.dreamtobe.cn/gpulido/4bae80a5be4fd5c7ed61f1f1667da039

这是我更改后的代码,你可以在codesandbox中使用:

import { MDCTextField } from "@material/textfield";
import { MDCMenu, DefaultFocusState, Corner } from "@material/menu";
import "./styles.scss";

const input = new MDCTextField(document.querySelector(".mdc-text-field"));
const menu = new MDCMenu(document.querySelector(".mdc-menu"));
menu.setDefaultFocusState(DefaultFocusState.NONE);
menu.setAnchorCorner(Corner.BOTTOM_START);
menu.setAnchorElement(input.component);

input.listen("focusin", () => {
  menu.open = true;
});
input.listen("click", () => {
  menu.open = true;
});
input.listen("focusout", () => {
  menu.open = false;
});

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接