В основном я работаю над проектом драм-машины, и мне нужно, чтобы каждая из 9 кнопок, которые будут отображаться на экране, вызывалась щелчком мыши, а также соответствующей клавишей клавиатуры.
Настроить его для работы с мышью с событием onClick
, прикрепленным к каждому нажатию кнопки, было довольно просто, но мне трудно заставить его работать с клавиатурой.
Пока что я сделал следующее:
1) Настройте componentDidMount()
с прослушивателем событий для чтения каждого нажатия клавиши:
componentDidMount() {
const setKey = (event) => { this.setState({ keyPressed: event.key.toUpperCase() }) }
document.addEventListener('keydown', setKey);
}
2) Настройте componentDidUpdate()
, чтобы проверять, находится ли нажатая в данный момент клавиша среди клавиш, которые используются в приложении, затем запускается функция handleClick
и передается пара аргументов:
componentDidUpdate() {
if (this.state.keyList.includes(this.state.keyPressed)) {
this.handleClick("keydown", this.state.keyPressed)
}
}
3) Наконец, handleClick
проверяет, является ли это событием «нажатие клавиши» или «щелчок», и воспроизводит соответствующий <audio>
:
handleClick(event) {
if (arguments[0] === "keydown") {
var audio = document.getElementById(arguments[1])
} else {
const { name, value } = event.target
this.setState({
displayValue: value
})
var audio = document.getElementById(name)
}
audio.paused ? audio.play() : audio.currentTime = 0
}
Мой код в настоящее время может воспроизводить соответствующий звук для обоих сценариев ios, но я не уверен, как заставить его отображать соответствующее значение от кнопки в случае, если я t запускается кнопкой клавиатуры, поскольку я не могу понять, как передать event.target
, как это делается для сценария onClick
.
Кроме того, вероятно, основная проблема заключается в том, что в конечном итоге я хотел бы установите CSS и Bootstrap для этого проекта, и кнопка должна менять свой цвет при воспроизведении, а также при нажатии на клавиатуру. То, что я сделал прямо сейчас, - это скорее обходной путь, и когда придет время его настроить, он не будет работать таким образом.
Могу ли я каким-либо образом запускать кнопки при нажатии соответствующих клавиш клавиатуры и вести себя так, как если бы я делал это через onClick
?
class App extends React.Component {
constructor() {
super()
this.state = {
displayValue: "",
keyPressed: "",
keyList: ["Q", "W", "E", "A", "S", "D", "Z", "X", "C"]
}
this.handleClick = this.handleClick.bind(this)
}
componentDidMount() {
const setKey = (event) => { this.setState({ keyPressed: event.key.toUpperCase() }) }
document.addEventListener('keydown', setKey)
}
componentDidUpdate() {
if (this.state.keyList.includes(this.state.keyPressed)) {
this.handleClick("keydown", this.state.keyPressed)
}
}
handleClick(event) {
if (arguments[0] === "keydown") {
var audio = document.getElementById(arguments[1])
} else {
const { name, value } = event.target
this.setState({
displayValue: value
})
var audio = document.getElementById(name)
}
audio.paused ? audio.play() : audio.currentTime = 0
}
render() {
return (
<div id="drum-machine">
<div id="display">{this.state.displayValue}</div>
<div className="drum-pad" id="pad-q">
<button type="button" name={this.state.keyList[0]} value="Chord 1" onClick={this.handleClick}>Q</button>
<audio className="clip" id={this.state.keyList[0]} src="https://s3.amazonaws.com/freecodecamp/drums/Chord_1.mp3"/>
</div>
<div className="drum-pad" id="pad-w">
<button type="button" name={this.state.keyList[1]} value="Chord 2" onClick={this.handleClick}>W</button>
<audio className="clip" id={this.state.keyList[1]} src="https://s3.amazonaws.com/freecodecamp/drums/Chord_2.mp3"/>
</div>
<div className="drum-pad" id="pad-e">
<button type="button" name={this.state.keyList[2]} value="Chord 3" onClick={this.handleClick}>E</button>
<audio className="clip" id={this.state.keyList[2]} src="https://s3.amazonaws.com/freecodecamp/drums/Chord_3.mp3"/>
</div>
<div className="drum-pad" id="pad-a">
<button type="button" name={this.state.keyList[3]} value="Shaker" onClick={this.handleClick}>A</button>
<audio className="clip" id={this.state.keyList[3]} src="https://s3.amazonaws.com/freecodecamp/drums/Give_us_a_light.mp3"/>
</div>
<div className="drum-pad" id="pad-s">
<button type="button" name={this.state.keyList[4]} value="Open HH" onClick={this.handleClick}>S</button>
<audio className="clip" id={this.state.keyList[4]} src="https://s3.amazonaws.com/freecodecamp/drums/Dry_Ohh.mp3"/>
</div>
<div className="drum-pad" id="pad-d">
<button type="button" name={this.state.keyList[5]} value="Closed HH" onClick={this.handleClick}>D</button>
<audio className="clip" id={this.state.keyList[5]} src="https://s3.amazonaws.com/freecodecamp/drums/Bld_H1.mp3"/>
</div>
<div className="drum-pad" id="pad-z">
<button type="button" name={this.state.keyList[6]} value="Punchy Kick" onClick={this.handleClick}>Z</button>
<audio className="clip" id={this.state.keyList[6]} src="https://s3.amazonaws.com/freecodecamp/drums/punchy_kick_1.mp3"/>
</div>
<div className="drum-pad" id="pad-x">
<button type="button" name={this.state.keyList[7]} value="Side Stick" onClick={this.handleClick}>X</button>
<audio className="clip" id={this.state.keyList[7]} src="https://s3.amazonaws.com/freecodecamp/drums/side_stick_1.mp3"/>
</div>
<div className="drum-pad" id="pad-c">
<button type="button" name={this.state.keyList[8]} value="Snare" onClick={this.handleClick}>C</button>
<audio className="clip" id={this.state.keyList[8]} src="https://s3.amazonaws.com/freecodecamp/drums/Brk_Snr.mp3"/>
</div>
</div>
)
}
}
ReactDOM.render(<App />, document.getElementById("root"))
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.3.1/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.3.1/umd/react-dom.production.min.js"></script>
<body>
<div id="root"></div>
</body>