用于 a11y 合规性的按键事件处理程序

Keypress event handler for a11y compliance

我正在努力使我的 React.JS 应用程序符合无障碍标准。

作为练习的一部分,我在使用 onClick 处理程序的地方添加了 onKeyDown 处理程序。我还用一个特殊的包装函数来包装这些处理​​程序,该函数检查按下了哪个键。实际代码如下:

import { KeyboardEvent } from 'react';
enum Keys {
  TAB = 9,
}
const handleKeyPress = (cb: () => void) => (e: KeyboardEvent) => {
  if (e.keyCode !== Keys.TAB) cb();
};
export { handleKeyPress };

我将其用作:

<div
  className={classes.link_complete}
  onClick={handleOnClick}
  onKeyDown={handleKeyPress(() => {
    handleOnClick();
  })}
  tabIndex={0}
  role="button"
>

这工作正常。但是,有些情况下我想将实际事件作为参数传递给 handleKeyPress 函数包装的函数。那对我不起作用。我试过了:

onClick={handleViewInfoClick}
onKeyDown={(e) => {
  console.log('detected keydown');
  handleKeyPress(() => {
    console.log('inside handler');
    handleViewInfoClick(e);
  });
}}

那是行不通的。检测到按键事件,因此我看到打印了 detected keydown。然而,里面的代码并没有被调用。

正确的做法是什么?

问题是 handleKeyPress return 是一个函数(这是有道理的,因为您通常对 onKeyDown 使用 return 值),但您不是在您尝试使用事件对象的示例中调用它,您只是调用 handleKeyPress 来创建函数,然后不调用函数。

我会修改 handleKeyPress 以便它传递事件对象:

const handleKeyPress = (cb: (e: KeyboardEvent) => void) => (e: KeyboardEvent) => {
  //                         ^^^^^^^^^^^^^^^^
  if (e.keyCode !== Keys.TAB) cb(e);
  //                             ^
};

那么用法几乎与您原来的用法完全一样,您只需包含处理程序:

<div
  className={classes.link_complete}
  onClick={handleOnClick}
  onKeyDown={handleKeyPress((e) => handleViewInfo(e))}
  tabIndex={0}
  role="button"
>

或更简洁:

<div
  className={classes.link_complete}
  onClick={handleOnClick}
  onKeyDown={handleKeyPress(handleViewInfo)}
  tabIndex={0}
  role="button"
>