我正在使用MDC Web组件构建自动完成输入。我有一个输入文本字段和一个菜单。您可以看到codeandox here。 我正在显示有关focusin事件的菜单,但是如果我开始在输入字段中写入内容,则菜单将立即关闭。
@Injectable({ providedIn: 'root' })
export class AuthGuard implements CanActivate {
constructor(private authService: AuthService, private router: Router) {}
canActivate(
route: ActivatedRouteSnapshot,
state: RouterStateSnapshot
):
| boolean
| UrlTree
| Promise<boolean | UrlTree>
| Observable<boolean | UrlTree> {
return this.authService.user.pipe(
map((user) => {
const isAuth = !!user;
if (isAuth) {
return true;
}
return this.router.createUrlTree(['/auth']);
})
);
}
}
我认为这是由于菜单默认行为在触发菜单外单击时关闭。这里的问题还在于焦点是来自文本字段的第一个菜单项。防止这种情况的方法是什么,并打开菜单直到焦点消失在输入字段上?
答案 0 :(得分:2)
这里的问题与可访问性有关,这是按顺序发生的事情:
当您单击输入时,输入将获得客户端“焦点”。
这将触发打开菜单的“ focusin”事件。
然后,根据accessibility documentation defined here,MDCMenu将自动聚焦第一个菜单项。
要阻止此焦点自动发生,我们可以设置
menu.setDefaultFocusState(DefaultFocusState.NONE);
DefaultFocusState.NONE
不改变焦点。如果您不希望菜单将焦点集中在打开上,请进行设置。 (例如,“自动完成”下拉菜单。)
如果这么简单,那就太好了,但是现在的问题是,如果MDCMenu
在没有焦点时自动关闭。
[edit]:这下一节是不正确的,锚点并没有打开,只是将其锚定在元素周围
要解决下一个问题,我们将MDCMenu
锚定到输入元素(必须是本机元素):
menu.setAnchorElement(document.querySelector(".mdc-text-field"));
最后,我们需要告诉MDCMenu
在从输入中移出焦点后关闭:
input.listen("focusout", () => {
menu.open = false;
});
您可能还需要调整其他一些问题,但我认为应该可以解决。有一个共享的代码示例,该示例也使用MDCMenu制作“自动填充下拉菜单”,您可以在此处参考:https://gist.dreamtobe.cn/gpulido/4bae80a5be4fd5c7ed61f1f1667da039
以下是我的更改的代码,您可以在代码和框中使用:
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;
});