辅助功能 - React确保点击事件具有关键事件

Raú*_*tín 6 javascript accessibility decorator reactjs

我想确保我的所有onClick事件都在onKeyDown事件旁边.

我将使用eslint-plugin-jsx-a11y来确保这一点.但是在代码中,这是一种通用的方法.我的意思是,一直这样做会很烦人:

 if(event.keyCode === 13){
    ...
 }
Run Code Online (Sandbox Code Playgroud)

我想有一种方法告诉一个元素,在onKeyDown中用户使用onClick中的执行函数.或类似的解决方案,如 http://www.karlgroves.com/2014/11/24/ridiculously-easy-trick-for-keyboard-accessibility/

以角度为例,我清楚了.让我们去指令自动执行此操作.但在React,我不知道这是最好的方法.


eslint规则:https: //github.com/evcohen/eslint-plugin-jsx-a11y/blob/master/docs/rules/click-events-have-key-events.md

cra*_*igb 9

没有装饰器的另一种方法可能是使用对象扩展来向元素添加必要的道具:

function buttonize(handlerFn) {
  return {
    role: 'button',
    onClick: handlerFn,
    onKeyDown: event => {
      // insert your preferred method for detecting the keypress
      if (event.keycode === 13) handlerFn(event);
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

并使用如下:

<div
  className="element-with-very-good-excuse-to-dont-be-a-button"
  {...buttonize(this.myAction)}
>click me</div>
Run Code Online (Sandbox Code Playgroud)


Raú*_*tín 7

最后我只看到2个解决方案:

1我可以创建一个封装所有这些操作的组件......但这是一个按钮的工作.我想不打开一种在我的项目中创建按钮的新方法,这只是用于异常,这可能会在项目内部产生恶意行为.为此,我们有另一个组件......按钮:)

2为动作创建装饰器.

export function a11yButtonActionHandler(target, key, descriptor) {
    const fn = descriptor.value;
    if (typeof fn !== 'function') {
        throw new Error(`@a11yButtonActionHandler decorator can only be applied to methods not: ${typeof fn}`);
    }

    descriptor.value = function actionHandler(event) {
        if (!event || event.type === 'click' ||
            (['keydown', 'keypress'].includes(event.type) && ['Enter', ' '].includes(event.key))
        ) {
            fn.call(this, event);
        }
    };

    return descriptor;
}
Run Code Online (Sandbox Code Playgroud)

并使用装饰器.

@a11yButtonActionHandler
myAction(event) {
 ...
}
Run Code Online (Sandbox Code Playgroud)
<div className="element-with-very-good-excuse-to-dont-be-a-button"
     role="button"
     tabIndex="0"
     onKeyDown={ this.myAction }
     onClick={ this.myAction }>
Run Code Online (Sandbox Code Playgroud)