Javascript onKeyPress无法';不能用“触发”;按钮“;反应

Javascript onKeyPress无法';不能用“触发”;按钮“;反应,javascript,html,reactjs,Javascript,Html,Reactjs,我正在制作一台鼓机,其中的一个挑战是为显示的键盘设置键盘事件。 请看一看我写的。当我按下键盘上的按钮时,没有触发任何事件。这里有什么问题吗?我做了一点研究,发现在大多数情况下,onKeyPress都会绑定到。onKeyPress只能与一起使用,这是真的吗 const键={ “Q-pad”:https://s3-us-west-2.amazonaws.com/s.cdpn.io/242518/SD0025.mp3", “W-pad”:https://s3-us-west-2.amazonaws.c

我正在制作一台鼓机,其中的一个挑战是为显示的键盘设置键盘事件。 请看一看我写的。当我按下键盘上的按钮时,没有触发任何事件。这里有什么问题吗?我做了一点研究,发现在大多数情况下,onKeyPress都会绑定到
。onKeyPress只能与
一起使用,这是真的吗

const键={
“Q-pad”:https://s3-us-west-2.amazonaws.com/s.cdpn.io/242518/SD0025.mp3",
“W-pad”:https://s3-us-west-2.amazonaws.com/s.cdpn.io/242518/SD0010.mp3",
“电子键盘”:https://s3-us-west-2.amazonaws.com/s.cdpn.io/242518/SD0000.mp3",
“A-pad”:https://s3-us-west-2.amazonaws.com/s.cdpn.io/242518/RS.mp3",
“S-pad”:https://s3-us-west-2.amazonaws.com/s.cdpn.io/242518/OH25.mp3",
“D-pad”:https://s3-us-west-2.amazonaws.com/s.cdpn.io/242518/MA.mp3",
“Z-pad”:https://s3-us-west-2.amazonaws.com/s.cdpn.io/242518/CY0010.mp3",
“X-pad”:https://s3-us-west-2.amazonaws.com/s.cdpn.io/242518/CH.mp3",
“C-pad”:https://s3-us-west-2.amazonaws.com/s.cdpn.io/242518/CB.mp3"
}
常量键盘=[“Q”、“W”、“E”、“A”、“S”、“D”、“Z”、“X”、“C”]
const audioQ=新音频()
类应用程序扩展了React.Component{
构造函数(){
超级()
这个州={
}
this.handleClick=this.handleClick.bind(this)
this.handleKeyPress=this.handleKeyPress(this)
}
handleKeyPress(事件){
console.log(event.key)
}
handleClick(事件){
const{name}=event.target
const playSound=新音频(键[名称])
playSound.play()
}
render(){
const keyboards组件=keyboards.map((键,索引)=>(
))
console.log(键盘组件)
返回(
滚筒机
{键盘组件}
)
}
}
ReactDOM.render(,document.getElementById(“app”);

您在这里遇到的问题与HTML和Javascript如何允许和处理用户输入有关。这是因为按钮输入并不总是处于“聚焦”状态,因此Javascript不会从元素接收输入事件,因为按钮严格来说不会接收任何事件

解决这个问题的方法是通过CSS实现。最常用的方法是使用如下所示的标准文本输入字段,该字段是自动聚焦的,并且可能作为侦听器,以便在用户单击元素外部时始终重新聚焦该元素

<input type="text" autoFocus onKeyPress={() => {...}}/>

现在,您的代码应该可以正常工作了,请记住输入字段不能被隐藏,因为它必须显示为DOM的有效成员才能接收和传输事件,并且只能使用CSS使其不可见。

这里遇到的问题与HTML和Javascript如何允许和处理用户输入有关。这是因为按钮输入并不总是处于“聚焦”状态,因此Javascript不会从元素接收输入事件,因为按钮严格来说不会接收任何事件

解决这个问题的方法是通过CSS实现。最常用的方法是使用如下所示的标准文本输入字段,该字段是自动聚焦的,并且可能作为侦听器,以便在用户单击元素外部时始终重新聚焦该元素

<input type="text" autoFocus onKeyPress={() => {...}}/>

现在,您的代码应该工作得很好,请记住输入字段不能被隐藏,因为它必须显示为DOM的有效成员才能接收和传输事件,并且只能使用CSS使其不可见。

我想您可能需要在这里重新思考
按键
事件应该附加到哪里关键事件需要关注,在您的情况下,我认为
文档
本身将是连接事件侦听器的好地方。我已经修改了你的密码笔来做同样的事情(使用
keydown
而不是
keypress
,因为它声明不推荐使用)

另一个小错误是你没有绑定你的
handleKeyPress
,直接调用它

新的React代码:-

const keys = {
  "Q-pad": "https://s3-us-west-2.amazonaws.com/s.cdpn.io/242518/SD0025.mp3",
  "W-pad": "https://s3-us-west-2.amazonaws.com/s.cdpn.io/242518/SD0010.mp3",
  "E-pad": "https://s3-us-west-2.amazonaws.com/s.cdpn.io/242518/SD0000.mp3",
  "A-pad": "https://s3-us-west-2.amazonaws.com/s.cdpn.io/242518/RS.mp3",
  "S-pad": "https://s3-us-west-2.amazonaws.com/s.cdpn.io/242518/OH25.mp3",
  "D-pad": "https://s3-us-west-2.amazonaws.com/s.cdpn.io/242518/MA.mp3",
  "Z-pad": "https://s3-us-west-2.amazonaws.com/s.cdpn.io/242518/CY0010.mp3",
  "X-pad": "https://s3-us-west-2.amazonaws.com/s.cdpn.io/242518/CH.mp3",
  "C-pad": "https://s3-us-west-2.amazonaws.com/s.cdpn.io/242518/CB.mp3"
};
const keyboards = ["Q", "W", "E", "A", "S", "D", "Z", "X", "C"];
const audioQ = new Audio();
class App extends React.Component {
  constructor() {
    super();
    this.state = {};
    this.handleClick = this.handleClick.bind(this);
    this.handleKeyPress = this.handleKeyPress.bind(this);
  }
  handleKeyPress(event) {
    const key = `${event.key.toUpperCase()}-pad`;
    this.handleAudioPlay(key);
  }

  componentDidMount() {
    document.addEventListener("keydown", this.handleKeyPress);
  }

  componentWillUnmount() {
    document.removeEventListener("keydown", this.handleKeyPress);
  }

  handleAudioPlay(name) {
    const playSound = new Audio(keys[name]);
    playSound?.play();
  }

  handleClick(event) {
    const { name: key } = event.target;
    this.handleAudioPlay(key);
  }
  render() {
    const keyboardsComponent = keyboards.map((key, index) => (
      <input
        type="button"
        className="drum-pad"
        id={key + "-pad" + index}
        value={key}
        name={key + "-pad"}
        onClick={this.handleClick}
      />
    ));
    return (
      <div className="container-box">
        <h1 className="title">Drum machine</h1>
        <div id="drum-machine" className="container">
          {keyboardsComponent}
        </div>
      </div>
    );
  }
}

ReactDOM.render(<App />, document.getElementById("app"));

const key={
“Q-pad”:https://s3-us-west-2.amazonaws.com/s.cdpn.io/242518/SD0025.mp3",
“W-pad”:https://s3-us-west-2.amazonaws.com/s.cdpn.io/242518/SD0010.mp3",
“电子键盘”:https://s3-us-west-2.amazonaws.com/s.cdpn.io/242518/SD0000.mp3",
“A-pad”:https://s3-us-west-2.amazonaws.com/s.cdpn.io/242518/RS.mp3",
“S-pad”:https://s3-us-west-2.amazonaws.com/s.cdpn.io/242518/OH25.mp3",
“D-pad”:https://s3-us-west-2.amazonaws.com/s.cdpn.io/242518/MA.mp3",
“Z-pad”:https://s3-us-west-2.amazonaws.com/s.cdpn.io/242518/CY0010.mp3",
“X-pad”:https://s3-us-west-2.amazonaws.com/s.cdpn.io/242518/CH.mp3",
“C-pad”:https://s3-us-west-2.amazonaws.com/s.cdpn.io/242518/CB.mp3"
};
常量键盘=[“Q”、“W”、“E”、“A”、“S”、“D”、“Z”、“X”、“C”];
const audioQ=新音频();
类应用程序扩展了React.Component{
构造函数(){
超级();
this.state={};
this.handleClick=this.handleClick.bind(this);
this.handleKeyPress=this.handleKeyPress.bind(this);
}
handleKeyPress(事件){
const key=`${event.key.toUpperCase()}-pad`;
此.handleAudioPlay(键);
}
componentDidMount(){
文件。添加了文本列表(“向下键”,此为手动按键);
}
组件将卸载(){
文件。移除VentListener(“向下键”,此为。handleKeyPress);
}
handleAudioPlay(名称){
const playSound=新音频(键[名称]);
播放声音?.play();
}
handleClick(事件){
const{name:key}=event.target;
此.handleAudioPlay(键);
}
render(){
const keyboards组件=keyboards.map((键,索引)=>(
));
返回(
滚筒机
{键盘组件}
);
}
}

ReactDOM.render(

我想你可能想重新考虑一下
按键
事件应该附加在哪里。关键事件需要焦点,在你的情况下,我认为
文档
本身将是附加事件侦听器的好地方。我有
const keys = {
  "Q-pad": "https://s3-us-west-2.amazonaws.com/s.cdpn.io/242518/SD0025.mp3",
  "W-pad": "https://s3-us-west-2.amazonaws.com/s.cdpn.io/242518/SD0010.mp3",
  "E-pad": "https://s3-us-west-2.amazonaws.com/s.cdpn.io/242518/SD0000.mp3",
  "A-pad": "https://s3-us-west-2.amazonaws.com/s.cdpn.io/242518/RS.mp3",
  "S-pad": "https://s3-us-west-2.amazonaws.com/s.cdpn.io/242518/OH25.mp3",
  "D-pad": "https://s3-us-west-2.amazonaws.com/s.cdpn.io/242518/MA.mp3",
  "Z-pad": "https://s3-us-west-2.amazonaws.com/s.cdpn.io/242518/CY0010.mp3",
  "X-pad": "https://s3-us-west-2.amazonaws.com/s.cdpn.io/242518/CH.mp3",
  "C-pad": "https://s3-us-west-2.amazonaws.com/s.cdpn.io/242518/CB.mp3"
};
const keyboards = ["Q", "W", "E", "A", "S", "D", "Z", "X", "C"];
const audioQ = new Audio();
class App extends React.Component {
  constructor() {
    super();
    this.state = {};
    this.handleClick = this.handleClick.bind(this);
    this.handleKeyPress = this.handleKeyPress.bind(this);
  }
  handleKeyPress(event) {
    const key = `${event.key.toUpperCase()}-pad`;
    this.handleAudioPlay(key);
  }

  componentDidMount() {
    document.addEventListener("keydown", this.handleKeyPress);
  }

  componentWillUnmount() {
    document.removeEventListener("keydown", this.handleKeyPress);
  }

  handleAudioPlay(name) {
    const playSound = new Audio(keys[name]);
    playSound?.play();
  }

  handleClick(event) {
    const { name: key } = event.target;
    this.handleAudioPlay(key);
  }
  render() {
    const keyboardsComponent = keyboards.map((key, index) => (
      <input
        type="button"
        className="drum-pad"
        id={key + "-pad" + index}
        value={key}
        name={key + "-pad"}
        onClick={this.handleClick}
      />
    ));
    return (
      <div className="container-box">
        <h1 className="title">Drum machine</h1>
        <div id="drum-machine" className="container">
          {keyboardsComponent}
        </div>
      </div>
    );
  }
}

ReactDOM.render(<App />, document.getElementById("app"));