在 ag-grid 中切换到自定义单元格渲染器

tabbing into custom cell renderers in ag-grid

我有一个 angular ag-grid 实现,其中有一些自定义单元格渲染器。它们呈现从按钮到切换状态到指向应用程序其他部分的链接的内容。

我最近 运行 遇到一个问题,只有键盘用户无法将这些单元格渲染器的内容切换到 "click" 元素。我试过将 tabindex="0" and/or 和 href="#" 放在这些元素上,以便它们出现在页面的 Tab 键顺序中,但它们获得焦点的唯一方法是用鼠标单击.

似乎 ag-grid 覆盖了键盘的默认行为,也许是用箭头键添加 addtl 功能等。但它似乎不能很好地与这些自定义渲染器一起使用...

下面是这些渲染器之一的简化​​版本示例。

@Component({
  selector: 'fave-renderer',
  template: `
    <i class="icon fave"
       tabindex="0"
       (click)="toggleFave()"></i>
  `,
  styles: [``]
})
export class FaveRendererComponent implements ICellRendererAngularComp {
  public params: any;

  agInit(params: any): void {
    this.params = params;
  }

  constructor(private resultsService: ResultsService) {}

  refresh(): boolean {return false;}

  toggleFave() {/*implementation not important... */}
}

因此,我最终采用了一种棘手的解决方法来解决此问题。正在发生的事情是 ag-grid 实现 custom keyboard events。例如,Enter 将开始编辑单元格,Arrow 键将在网格中导航,Tab 导航到下一个单元格,依此类推。

因为 ag-grid 覆盖了默认的键盘事件,任何具有可聚焦元素的嵌套单元格渲染器在使用 Tab 键时永远不会获得焦点,因为 Tab 键正在由 ag-grid 处理。为了防止这种情况,我为 Suppress Keyboard Events handler.

添加了回调

在回调中,我只允许 ag-grid 处理选项卡导航,当当前被标记的焦点元素是单元格的最后一个可聚焦的子元素时(或者在 shift-tab 的情况下是单元格本身).

suppressKeyboardEvent(params: SuppressKeyboardEventParams) {
  const e = params.event;
  if (e.code == 'Tab' || e.key == 'Tab') {
    //get focusable children of parent cell
    let focusableChildrenOfParent = e.srcElement.closest(".ag-cell")
      .querySelectorAll('button, [href], :not(.ag-hidden) > input, select, textarea, [tabindex]:not([tabindex="-1"])');

    if (focusableChildrenOfParent.length == 0 ||
      (e.shiftKey == false && e.srcElement == focusableChildrenOfParent[focusableChildrenOfParent.length - 1]) ||
      (e.shiftKey == true && e.srcElement == focusableChildrenOfParent[0]) ||
      (e.shiftKey == true && e.srcElement.classList.contains("ag-cell")))
      return false; //do not suppress
    return true; //suppress
  }
  return false; //do not suppress by default
}