在React中,按下键盘时应用“Active”样式到按钮

3
我有一个使用React/Redux编写的鼓应用程序,它已经完全可以使用,但是我希望在按下相应的键时能够应用活动按钮样式,就像在物理上点击按钮时一样。目前,点击按钮会进行转换,但输入相应的键只会播放音频文件,与按钮没有真正的关联。是否有一种方法可以在按键时标记相应的按钮为活动状态?
这是我的CodeSandbox: https://codesandbox.io/s/k29r3928z7
1个回答

1

这是一个使用ref的完美案例(正如文档所说,不要滥用它)。

对于每个按钮,您需要一个指向DOM元素的“引用(ref)”。当您按下一个键并在json中找到其代码时,将访问相应的按钮引用并触发“focus”方法,以指示UI该按钮已被按下。

您的按钮定义应类似于以下内容:

{drumObj.map(x => (
      <button
        className="drum-pad"
        ref={"drumButton" + x.trigger}
        key={x.id}
        id={x.id}
        onClick={() => drumHit(x.url, x.id)}
      > ...

我们动态地为每个按钮设置一个引用名称(尝试在组件中定义一个唯一的引用名称前缀,并仅在一个位置进行定义),基于它所代表的字符。一旦我们存储了这些引用,我们可以在需要时像这样在 handleKeyPress 方法中访问它们:
handleKeyPress = event => {
   const drumKey = drumObj.find(obj => obj.keyCode === event.keyCode);

   if (drumKey) {
     this.refs["drumButton" + drumKey.trigger].focus();
     this.props.drumHit(drumKey.url, drumKey.id);
   }
};

实际上我会用以下内容替换对this.props.drumHit(...)的调用:

this.refs["drumButton" + drumKey.trigger].click();

这是因为,如果将来您更改drumHit方法名称或签名,您只需要在按钮属性定义的onClick属性中更新它。作为一种良好的实践,始终尝试通过编程方式模拟此类事件,而不是在代码的不同部分复制相同的行为。
因此,您的handleKeyPress方法应该如下所示:
handleKeyPress = event => {
   const drumKey = drumObj.find(obj => obj.keyCode === event.keyCode);

   if (drumKey) {
     this.refs["drumButton" + drumKey.trigger].click();
     this.refs["drumButton" + drumKey.trigger].focus();
   }
};

我希望它有所帮助!

问候, Max。


这会将焦点转移到按钮,但不会触发过渡即在之前...之后。除了你所说的方法,还有其他方法可以实现吗?我也感谢您提供的额外信息! - Cdhippen
我刚刚想到了!我将我的CSS更改为focus:after,然后添加了一个.blur()调用,以便在元素被按下时立即将焦点转移。 - Cdhippen
1
那就是正确的方法。你增加了所需的样式并模拟了动作。恭喜!;) - Max Tomasello

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接