在 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
}
我有一个 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
}