mat-select inside mat-sidenav 在 sidenav 打开时自动聚焦

Posted

技术标签:

【中文标题】mat-select inside mat-sidenav 在 sidenav 打开时自动聚焦【英文标题】:mat-select inside mat-sidenav auto-focused when sidenav is opened 【发布时间】:2018-06-25 19:41:08 【问题描述】:

当在 mat-sidenav 中有一个 mat-select 以编程方式打开时,mat-select 获得焦点,并且(如果内容允许),sidenav 滚动到焦点元素。

如何防止焦点和滚动?目前,我通过在 mat-sidenav 顶部添加额外的 mat-select 并将高度设置为 0 并将溢出设置为隐藏来使用丑陋的 hack,但我想知道是否有更合适和优雅的解决方案。

该问题的最低限度演示:https://angular-bg7azm.stackblitz.io

演示正在使用:

@angular/core @ 5.2.0 @angular/material @ 5.0.0-rc.3

我正在使用:

@angular/code@4.3.0 @angular/material @ 2.0.0-beta.12

【问题讨论】:

【参考方案1】:

我一直在尝试为基本相同的问题找到一个好的解决方案 - 没有使用 tabindex="-1" 的任何项目最初都集中在对话框上。我想出的一个解决方案与您的“黑客”想法基本相同,但更聪明一些。这是一个非常简单的自定义组件,它使用 CDK 指令来获取初始焦点,然后在模糊时自行移除。组件的不透明度和大小为零,因此它是不可见的并且不占用空间。除了该组件具有初始焦点之外,Tab 顺序被保留。您可以通过将自定义组件放置在您的 DOM 中,在您希望成为第一个元素的有效标签顺序之前,控制哪个项目在第一次 TAB 按下时具有焦点。因为该组件是通过 ngIf 在 blur 时移除的,所以一旦用户与某物交互,它就不再处于 Tab 键顺序。

注意:“cdkFocusInitial”指令来自 Material 5.x。在 2.0.0-beta.12 中,它是“cdk-focus-initial”。另外 - 我只用 5.x 测试过。

组件代码:

import  Component  from '@angular/core';

@Component(
  selector: 'init-focus',
  template: '<button cdkFocusInitial *ngIf="!blurred" (blur)="blurred = true"></button>',
  styles: [':host()  opacity: 0; max-width: 0; min-width: 0; max-height: 0; min-height: 0; margin: 0; padding: 0; border-width: 0; ']
)
export class InitFocus 
  public blurred = false;
  constructor()  

部分 html 示例(来自您的 stackblitz):

<mat-list-item>
    <init-focus></init-focus>
    <mat-form-field>
        <mat-select placeholder="Status">
            <mat-option value="open">Openstaand</mat-option>
            <mat-option value="assigned">Toegekend</mat-option>
            <mat-option value="in_progress">In behandeling</mat-option>
            <mat-option value="closed_resolved">Opgelost</mat-option>
            <mat-option value="closed_not_resolved">Niet opgelost</mat-option>
            <mat-option value="not_relevant">Niet relevant</mat-option>
        </mat-select>
    </mat-form-field>
</mat-list-item>

我不确定这在不同的用例中有多强大,可能有办法对此进行改进,但它似乎在对话框和 sidenav 中运行良好。

【讨论】:

好吧,对于对话框,Material v5 中有一个更简单的解决方案 - 将 autoFocus: false 添加到 MatDialogConfig 对象。 :) 感谢您提供替代方案,但由于这也是一个“黑客”,我将暂时保留我的解决方案。它工作得很好,我的客户没有更多的抱怨。所以,目标实现了;)

以上是关于mat-select inside mat-sidenav 在 sidenav 打开时自动聚焦的主要内容,如果未能解决你的问题,请参考以下文章

以编程方式设置 <mat-select> 的值

FormArray 和 formGroup 中的 Angular Material mat-select

当值是数字时不显示 mat-select 值

在mat-select上重新选择相同值时触发事件

<mat-select> 多选(formControl)

ng-deep 导致 Angular 中的 mat-select 出现问题