ReactJS - 如何在 onKeyPress 和 onClick 上播放音频元素?
ReactJS - How do I play an audio element onKeyPress and onClick?
所以我正在尝试从 freeCodeCamp 构建 Drum Machine 项目,但我遇到了音频元素的这个问题。我写了下面的代码。我没有收到任何错误,但是当我用 class“鼓垫”单击 div 时,音频仍然无法播放。我知道如何在没有 audio 元素的情况下完成这项工作,但挑战需要专门使用该元素。
我仍然会尝试自己解决这个问题,如果我在其他地方找到解决方案,我会更新这个问题。
这是我的 DrumPad 组件
import React from 'react';
class DrumPad extends React.Component {
constructor(props){
super(props);
this.state = {
name: this.props.name,
audio: this.props.source,
indexNr: this.props.indexNr,
keyId: this.props.keyId
}
this.clickHandle = this.clickHandle.bind(this);
this.keyPressHandle = this.keyPressHandle.bind(this);
}
clickHandle() {
document.getElementById(`audio${this.state.indexNr}`).play();
}
keyPressHandle(event) {
if(event.key === this.state.keyId || event.key === this.state.keyId.toLowerCase()){
document.getElementById(`audio${this.state.indexNr}`).play();
}
}
render(){
return (
<div className="drum-pad" id={this.name} onClick={this.clickHandle} onKeyPress={this.keyPressHandle}>
<h3>{this.state.keyId}</h3>
<audio id={`audio${this.state.indexNr}`} src={this.audio} />
</div>
)
}
}
export default DrumPad;
这是我的键盘组件
import DrumPad from "./DrumpPad";
const Keyboard = (props) => {
return <div className="column1">
{
soundsArr.map((sound, index) => <DrumPad key={index} indexNr={index} name={sound.name} source={sound.source} keyId={sound.keyId} />)
}
</div>
}
export default Keyboard;
const soundsArr = [
{
name: "Drum0",
source: "https://s3.amazonaws.com/freecodecamp/drums/Heater-6.mp3",
keyId: "Q"
},
{
name: "Drum1",
source: "https://s3.amazonaws.com/freecodecamp/drums/Heater-6.mp3",
keyId: "W"
},
{
name: "Drum2",
source: "https://s3.amazonaws.com/freecodecamp/drums/Heater-6.mp3",
keyId: "E"
},
{
name: "Drum3",
source: "https://s3.amazonaws.com/freecodecamp/drums/Heater-6.mp3",
keyId: "A"
},
{
name: "Drum4",
source: "https://s3.amazonaws.com/freecodecamp/drums/Heater-6.mp3",
keyId: "S"
},
{
name: "Drum5",
source: "https://s3.amazonaws.com/freecodecamp/drums/Heater-6.mp3",
keyId: "D"
},
{
name: "Drum6",
source: "https://s3.amazonaws.com/freecodecamp/drums/Heater-6.mp3",
keyId: "Z"
},
{
name: "Drum7",
source: "https://s3.amazonaws.com/freecodecamp/drums/Heater-6.mp3",
keyId: "X"
},
{
name: "Drum8",
source: "https://s3.amazonaws.com/freecodecamp/drums/Heater-6.mp3",
keyId: "C"
}
];
很多。但这是我编辑代码的方式。
在 DrumPad
组件中,您将所有道具添加到状态。这不是必需的,因为您没有更改任何值,因此最好从 Class
to a Function
组件转换组件。
您向 DrumPad
组件中的父 div
元素添加了一个 onKeyPress
事件。那永远不会 运行 因为元素无法聚焦。因此,您应该使用 useEffect
挂钩将事件附加到 window
并播放音频。
不建议使用数组的索引作为key prop。您应该使用 DrumPad
的 name
和 keyId
,因为它已经是唯一的。在Keyboard
组件的render
函数中。
根据上一点,您可以使用key
或name
来生成音频的id。这意味着不需要传递 indexNr
道具。或者您可以使用 useRef
挂钩访问 audio
所以我正在尝试从 freeCodeCamp 构建 Drum Machine 项目,但我遇到了音频元素的这个问题。我写了下面的代码。我没有收到任何错误,但是当我用 class“鼓垫”单击 div 时,音频仍然无法播放。我知道如何在没有 audio 元素的情况下完成这项工作,但挑战需要专门使用该元素。
我仍然会尝试自己解决这个问题,如果我在其他地方找到解决方案,我会更新这个问题。
这是我的 DrumPad 组件
import React from 'react';
class DrumPad extends React.Component {
constructor(props){
super(props);
this.state = {
name: this.props.name,
audio: this.props.source,
indexNr: this.props.indexNr,
keyId: this.props.keyId
}
this.clickHandle = this.clickHandle.bind(this);
this.keyPressHandle = this.keyPressHandle.bind(this);
}
clickHandle() {
document.getElementById(`audio${this.state.indexNr}`).play();
}
keyPressHandle(event) {
if(event.key === this.state.keyId || event.key === this.state.keyId.toLowerCase()){
document.getElementById(`audio${this.state.indexNr}`).play();
}
}
render(){
return (
<div className="drum-pad" id={this.name} onClick={this.clickHandle} onKeyPress={this.keyPressHandle}>
<h3>{this.state.keyId}</h3>
<audio id={`audio${this.state.indexNr}`} src={this.audio} />
</div>
)
}
}
export default DrumPad;
这是我的键盘组件
import DrumPad from "./DrumpPad";
const Keyboard = (props) => {
return <div className="column1">
{
soundsArr.map((sound, index) => <DrumPad key={index} indexNr={index} name={sound.name} source={sound.source} keyId={sound.keyId} />)
}
</div>
}
export default Keyboard;
const soundsArr = [
{
name: "Drum0",
source: "https://s3.amazonaws.com/freecodecamp/drums/Heater-6.mp3",
keyId: "Q"
},
{
name: "Drum1",
source: "https://s3.amazonaws.com/freecodecamp/drums/Heater-6.mp3",
keyId: "W"
},
{
name: "Drum2",
source: "https://s3.amazonaws.com/freecodecamp/drums/Heater-6.mp3",
keyId: "E"
},
{
name: "Drum3",
source: "https://s3.amazonaws.com/freecodecamp/drums/Heater-6.mp3",
keyId: "A"
},
{
name: "Drum4",
source: "https://s3.amazonaws.com/freecodecamp/drums/Heater-6.mp3",
keyId: "S"
},
{
name: "Drum5",
source: "https://s3.amazonaws.com/freecodecamp/drums/Heater-6.mp3",
keyId: "D"
},
{
name: "Drum6",
source: "https://s3.amazonaws.com/freecodecamp/drums/Heater-6.mp3",
keyId: "Z"
},
{
name: "Drum7",
source: "https://s3.amazonaws.com/freecodecamp/drums/Heater-6.mp3",
keyId: "X"
},
{
name: "Drum8",
source: "https://s3.amazonaws.com/freecodecamp/drums/Heater-6.mp3",
keyId: "C"
}
];
很多。但这是我编辑代码的方式。
在
DrumPad
组件中,您将所有道具添加到状态。这不是必需的,因为您没有更改任何值,因此最好从Class
to aFunction
组件转换组件。您向
DrumPad
组件中的父div
元素添加了一个onKeyPress
事件。那永远不会 运行 因为元素无法聚焦。因此,您应该使用useEffect
挂钩将事件附加到window
并播放音频。不建议使用数组的索引作为key prop。您应该使用
DrumPad
的name
和keyId
,因为它已经是唯一的。在Keyboard
组件的render
函数中。根据上一点,您可以使用
key
或name
来生成音频的id。这意味着不需要传递indexNr
道具。或者您可以使用useRef
挂钩访问audio