如何通过音频播放声音on单击React中的父元素。我不确定什么是正确的方法。有人建议我使用裁判,但是以什么方式?放在哪里?在div上包含音频标签还是音频标签本身?但是当我单击时,我单击div,而不是音频标签。那么当您单击音频的父级时,如何播放音频中的声音? 这是我的代码:
import React from 'react';
import ReactDOM from 'react-dom';
import 'bootstrap/dist/css/bootstrap.min.css';
import './style.css';
class DrumMachine extends React.Component {
constructor(props) {
super(props);
this.state = {
pressedKey: null,
display: null,
sliderVal: 50,
volume: 0.5,
mySwitch: true,
mySwitchBox: true,
prevVolume: 0.5,
fancy: false,
};
this.handleClick = this.handleClick.bind(this);
this.keyPress = this.keyPress.bind(this);
this.handleVolume = this.handleVolume.bind(this);
this.onOff = this.onOff.bind(this);
this.fancyToggle = this.fancyToggle.bind(this);
this.myRef = React.createRef();
this.mySwitchOn = React.createRef();
this.mySwitchOff = React.createRef();
//Refs of audio elements.
this.Q = React.createRef();
this.W = React.createRef();
this.E = React.createRef();
this.A = React.createRef();
this.S = React.createRef();
this.D = React.createRef();
this.Z = React.createRef();
this.X = React.createRef();
this.C = React.createRef();
//Refs of divs who are parents of audio.
this.H1 = React.createRef();
this.H2 = React.createRef();
this.H3 = React.createRef();
this.H41 = React.createRef();
this.H6 = React.createRef();
this.Dsc_Oh = React.createRef();
this.Kick_n_Hat = React.createRef();
this.RP4_KICK_1 = React.createRef();
this.Cev_H2 = React.createRef();
this.myRange = React.createRef();
this.sounds = {
sound1: null,
sound2: null,
sound3: null,
sound4: null,
sound5: null,
sound6: null,
sound7: null,
sound8: null,
sound9: null
};
this.parents = {
parent1: null,
parent2: null,
parent3: null,
parent4: null,
parent5: null,
parent6: null,
parent7: null,
parent8: null,
parent9: null
};
this.tracks = {
track1: ["https://s3.amazonaws.com/freecodecamp/drums/Heater-1.mp3", "https://s3.amazonaws.com/freecodecamp/drums/Heater-2.mp3", "https://s3.amazonaws.com/freecodecamp/drums/Heater-3.mp3", "https://s3.amazonaws.com/freecodecamp/drums/Heater-4_1.mp3", "https://s3.amazonaws.com/freecodecamp/drums/Heater-6.mp3", "https://s3.amazonaws.com/freecodecamp/drums/Dsc_Oh.mp3", "https://s3.amazonaws.com/freecodecamp/drums/Kick_n_Hat.mp3", "https://s3.amazonaws.com/freecodecamp/drums/RP4_KICK_1.mp3", "https://s3.amazonaws.com/freecodecamp/drums/Cev_H2.mp3"],
track2: ["https://s3.amazonaws.com/freecodecamp/drums/Chord_1.mp3", "https://s3.amazonaws.com/freecodecamp/drums/Chord_2.mp3", "https://s3.amazonaws.com/freecodecamp/drums/Chord_3.mp3", "https://s3.amazonaws.com/freecodecamp/drums/Give_us_a_light.mp3", "https://s3.amazonaws.com/freecodecamp/drums/Dry_Ohh.mp3", "https://s3.amazonaws.com/freecodecamp/drums/Bld_H1.mp3", "https://s3.amazonaws.com/freecodecamp/drums/punchy_kick_1.mp3", "https://s3.amazonaws.com/freecodecamp/drums/side_stick_1.mp3", "https://s3.amazonaws.com/freecodecamp/drums/Brk_Snr.mp3"],
};
this.Id = {
id1: ["Heater-1", "Heater-2", "Heater-3", "Heater-4", "Clap", "Open-HH", "Kick n' Hat", "Kick", "Closed-HH"],
id2: ["Chord-1", "Chord-2", "Chord-3", "Shaker", "Open-HH", "Closed-HH", "Punchy-Kick", "Side-Stick", "Snare"],
};
}
componentDidMount() {
window.addEventListener("keydown", this.keyPress);
this.sounds = {
sound1: ReactDOM.findDOMNode(this.Q.current),
sound2: ReactDOM.findDOMNode(this.W.current),
sound3: ReactDOM.findDOMNode(this.E.current),
sound4: ReactDOM.findDOMNode(this.A.current),
sound5: ReactDOM.findDOMNode(this.S.current),
sound6: ReactDOM.findDOMNode(this.D.current),
sound7: ReactDOM.findDOMNode(this.Z.current),
sound8: ReactDOM.findDOMNode(this.X.current),
sound9: ReactDOM.findDOMNode(this.C.current)
};
this.parents = {
parent1: ReactDOM.findDOMNode(this.H1.current),
parent2: ReactDOM.findDOMNode(this.H2.current),
parent3: ReactDOM.findDOMNode(this.H3.current),
parent4: ReactDOM.findDOMNode(this.H41.current),
parent5: ReactDOM.findDOMNode(this.H6.current),
parent6: ReactDOM.findDOMNode(this.Dsc_Oh.current),
parent7: ReactDOM.findDOMNode(this.Kick_n_Hat.current),
parent8: ReactDOM.findDOMNode(this.RP4_KICK_1.current),
parent9: ReactDOM.findDOMNode(this.Cev_H2.current)
};
}
componentWillUnmount() {
window.removeEventListener("keydown", this.keyPress);
this.sounds = {
sound1: ReactDOM.findDOMNode(this.Q.current),
sound2: ReactDOM.findDOMNode(this.W.current),
sound3: ReactDOM.findDOMNode(this.E.current),
sound4: ReactDOM.findDOMNode(this.A.current),
sound5: ReactDOM.findDOMNode(this.S.current),
sound6: ReactDOM.findDOMNode(this.D.current),
sound7: ReactDOM.findDOMNode(this.Z.current),
sound8: ReactDOM.findDOMNode(this.X.current),
sound9: ReactDOM.findDOMNode(this.C.current)
};
this.parents = {
parent1: ReactDOM.findDOMNode(this.H1.current).id,
parent2: ReactDOM.findDOMNode(this.H2.current).id,
parent3: ReactDOM.findDOMNode(this.H3.current).id,
parent4: ReactDOM.findDOMNode(this.H41.current).id,
parent5: ReactDOM.findDOMNode(this.H6.current).id,
parent6: ReactDOM.findDOMNode(this.Dsc_Oh.current).id,
parent7: ReactDOM.findDOMNode(this.Kick_n_Hat.current).id,
parent8: ReactDOM.findDOMNode(this.RP4_KICK_1.current).id,
parent9: ReactDOM.findDOMNode(this.Cev_H2.current).id
};
}
keyPress(event){
let myKey = event.key;
let displayId;
switch (myKey.toUpperCase()) {
case this.Q.current.id:
this.sounds.sound1.volume = this.state.volume;
this.sounds.sound1.play();
if(this.state.volume===0){
displayId = null;
}
else{
displayId = this.parents.parent1.id;
}
break;
case this.W.current.id:
this.sounds.sound2.volume = this.state.volume;
this.sounds.sound2.play();
if(this.state.volume===0){
displayId = null;
}
else{
displayId = this.parents.parent2.id;
}
break;
case this.E.current.id:
this.sounds.sound3.volume = this.state.volume;
this.sounds.sound3.play();
if(this.state.volume===0){
displayId = null;
}
else{
displayId = this.parents.parent3.id;
}
break;
case this.A.current.id:
this.sounds.sound4.volume = this.state.volume;
this.sounds.sound4.play();
if(this.state.volume===0){
displayId = null;
}
else{
displayId = this.parents.parent4.id;
}
break;
case this.S.current.id:
this.sounds.sound5.volume = this.state.volume;
this.sounds.sound5.play();
if(this.state.volume===0){
displayId = null;
}
else{
displayId = this.parents.parent5.id;
}
break;
case this.D.current.id:
this.sounds.sound6.volume = this.state.volume;
this.sounds.sound6.play();
if(this.state.volume===0){
displayId = null;
}
else{
displayId = this.parents.parent6.id;
}
break;
case this.Z.current.id:
this.sounds.sound7.volume = this.state.volume;
this.sounds.sound7.play();
if(this.state.volume===0){
displayId = null;
}
else{
displayId = this.parents.parent7.id;
}
break;
case this.X.current.id:
this.sounds.sound8.volume = this.state.volume;
this.sounds.sound8.play();
if(this.state.volume===0){
displayId = null;
}
else{
displayId = this.parents.parent8.id;
}
break;
case this.C.current.id:
this.sounds.sound9.volume = this.state.volume;
this.sounds.sound9.play();
if(this.state.volume===0){
displayId = null;
}
else{
displayId = this.parents.parent9.id;
}
break;
default:
}
this.setState({
display: displayId,
});
}
handleClick(e){
let displayId;
switch (e.target.id) {
case this.H1.current.id:
this.sounds.sound1.volume = this.state.volume;
this.sounds.sound1.play();
if(this.state.volume===0){
displayId = null;
}
else{
displayId = this.parents.parent1.id;
}
break;
case this.H2.current.id:
this.sounds.sound2.volume = this.state.volume;
this.sounds.sound2.play();
if(this.state.volume===0){
displayId = null;
}
else{
displayId = this.parents.parent2.id;
}
break;
case this.H3.current.id:
this.sounds.sound3.volume = this.state.volume;
this.sounds.sound3.play();
if(this.state.volume===0){
displayId = null;
}
else{
displayId = this.parents.parent3.id;
}
break;
case this.H41.current.id:
this.sounds.sound4.volume = this.state.volume;
this.sounds.sound4.play();
if(this.state.volume===0){
displayId = null;
}
else{
displayId = this.parents.parent4.id;
}
break;
case this.H6.current.id:
this.sounds.sound5.volume = this.state.volume;
this.sounds.sound5.play();
if(this.state.volume===0){
displayId = null;
}
else{
displayId = this.parents.parent5.id;
}
break;
case this.Dsc_Oh.current.id:
this.sounds.sound6.volume = this.state.volume;
this.sounds.sound6.play();
if(this.state.volume===0){
displayId = null;
}
else{
displayId = this.parents.parent6.id;
}
break;
case this.Kick_n_Hat.current.id:
this.sounds.sound7.volume = this.state.volume;
this.sounds.sound7.play();
if(this.state.volume===0){
displayId = null;
}
else{
displayId = this.parents.parent7.id;
}
break;
case this.RP4_KICK_1.current.id:
this.sounds.sound8.volume = this.state.volume;
this.sounds.sound8.play();
if(this.state.volume===0){
displayId = null;
}
else{
displayId = this.parents.parent8.id;
}
break;
case this.Cev_H2.current.id:
this.sounds.sound9.volume = this.state.volume;
this.sounds.sound9.play();
if(this.state.volume===0){
displayId = null;
}
else{
displayId = this.parents.parent9.id;
}
break;
default:
}
this.setState({
display: displayId,
});
}
handleVolume(e){
this.setState({
volume: e.target.value/100,
sliderVal: e.target.value,
prevVolume: e.target.value/100,
});
}
onOff(e){
if(this.state.mySwitch){
this.setState({
mySwitch: !this.state.mySwitch,
mySwitchBox: !this.state.mySwitchBox,
volume: 0,
});
}
else{
this.setState({
mySwitch: !this.state.mySwitch,
mySwitchBox: !this.state.mySwitchBox,
volume: this.state.prevVolume,
});
}
}
fancyToggle(e){
this.setState({
fancy: e.target.checked
});
}
render(){
const displayId = this.state.display ? this.state.display : "No sound";
const mySwitch = this.state.mySwitch ? "switchOn" : "switchOff";
const mySwitchBox = this.state.mySwitchBox ? "switchBoxOn" : "switchBoxOff";
const switchText = this.state.mySwitch ? "On" : "Off";
const fancyId = this.state.fancy ? this.Id.id2.map(item2 => item2.replace("-"," ")) : this.Id.id1.map(item1 => item1.replace("-"," "));
const track = this.state.fancy ? this.tracks.track2 : this.tracks.track1;
console.log("***");
console.log(fancyId);
console.log(track);
console.log("***");
return(
<div id="drum-machine" className="grid-container cent" ref={this.myRef}>
<div id="display" className="item1">{displayId}</div>
<div id={fancyId[0]} ref={this.H1} className="drum-pad btn btn-warning" onClick={this.handleClick}>
Q<audio id="Q" ref={this.Q} className="clip">
<source src={track[0]} type="audio/mp3"></source>
</audio>
</div>
<div id={fancyId[1]} ref={this.H2} className="drum-pad btn btn-warning" onClick={this.handleClick}>
W<audio id="W" ref={this.W} className="clip">
<source src={track[1]}></source>
</audio>
</div>
<div id={fancyId[2]} ref={this.H3} className="drum-pad btn btn-warning" onClick={this.handleClick}>
E<audio id="E" ref={this.E} className="clip">
<source src={track[2]} type="audio/mp3"></source>
</audio>
</div>
<div id={fancyId[3]} ref={this.H41} className="drum-pad btn btn-warning" onClick={this.handleClick}>
A<audio id="A" ref={this.A} className="clip">
<source src={track[3]} type="audio/mp3"></source>
</audio>
</div>
<div id={fancyId[4]} ref={this.H6} className="drum-pad btn btn-warning" onClick={this.handleClick}>
S<audio id="S" ref={this.S} className="clip">
<source src={track[4]} type="audio/mp3"></source>
</audio>
</div>
<div id={fancyId[5]} ref={this.Dsc_Oh} className="drum-pad btn btn-warning" onClick={this.handleClick}>
D<audio id="D" ref={this.D} className="clip">
<source src={track[5]} type="audio/mp3"></source>
</audio>
</div>
<div id={fancyId[6]} ref={this.Kick_n_Hat} className="drum-pad btn btn-warning" onClick={this.handleClick}>
Z<audio id="Z" ref={this.Z} className="clip">
<source src={track[6]} type="audio/mp3"></source>
</audio>
</div>
<div id={fancyId[7]} ref={this.RP4_KICK_1} className="drum-pad btn btn-warning" onClick={this.handleClick}>
X<audio id="X" ref={this.X} className="clip">
<source src={track[7]} type="audio/mp3"></source>
</audio>
</div>
<div id={fancyId[8]} ref={this.Cev_H2} className="drum-pad btn btn-warning" onClick={this.handleClick}>
C<audio id="C" ref={this.C} className="clip">
<source src={track[8]} type="audio/mp3"></source>
</audio>
</div>
<div className="item3">
<input id="switch" type="checkbox" onChange={this.fancyToggle}/>
<div className="wrap">
<label htmlFor="switch"><span className="rib"></span><span className="rib"></span><span className="rib"></span></label>
</div>
</div>
<div className="item2">
<input type="range" min="1" max="100" value={this.state.sliderVal} className="slider" id="myRange" ref={this.myRange} onChange={this.handleVolume}/>
<div className="vol">Volume {this.state.sliderVal}</div>
</div>
<div id="sw" className={mySwitchBox} onClick={this.onOff}>
<div className={mySwitch} ref={this.mySwitchOn}>{switchText}</div>
</div>
</div>
);
}
}
ReactDOM.render(<DrumMachine/>, document.getElementById('root'));
忽略注释掉的代码,有人对我说,这样做不是上帝的方式。另外,所说的代码是我已经尝试过的。这里正在工作example code.
更新的代码。现在,剩下要做的就是左下角的按钮,它可以在两个音轨集合之间交替显示。实际上,它可以实现预期的效果,但声音保持不变。在检查音频的源子标签后,我没有发现错误,也没有发现任何问题。它有适当的文件可以播放...令我感到困惑的是,这里的问题是什么,因为所有内容都符合规范...该按钮应该做什么:单击该按钮后,它应该更改包含音频元素的所有div ID,更改为render()中的fancyId变量中声明的值,也应该更改为render()中的变量轨道中声明的其他音频轨道。通过在许多地方使用console.log(),我无法查明问题出在哪里。我在单击按钮后检查了音频元素,然后更改了音频源。我跳来跳去,新的眼睛可以让我了解到我目前所处的这种不稳定状况。
Edit2:我想我找到了解决方案。而不是检查复选框是否例如在render()中按下(选中)了“按钮”,我在播放声音的方法(即handleClick()和keyPress())中检查了该状态(奇特)。因此,...如果为假,则使用一组声音,如果为假,则使用其他声音。检查codepen,它已更新。
答案 0 :(得分:0)
首先,我将使用一个播放器而不是多个播放器,并将所有这些音频URL放入一个数组中,然后将它们作为文本链接列表循环放入render方法中。当用户单击链接时,我会通过状态用当前音频文件加载该播放器。像这样:
constructor () {
super()
this.state = {
currentAudioFile: 0,
}
this.audiofiles = [
{
label: 'Heater-1',
url: 'https://s3.amazonaws.com/freecodecamp/drums/Heater-1.mp3'
},
{
label: 'Heater-2',
url: 'https://s3.amazonaws.com/freecodecamp/drums/Heater-2.mp3'
},
...
]
}
然后在render方法中:
render () {
return (
<div>
<audio id="Player" controls>
<source src={this.audiofiles[this.state.currentAudioFile].url} type="audio/mp3"></source>
</audio>
<ul>
{
this.audiofiles.map((item,i) => (
<li>
<span
onClick={() => {
this.setState({
currentAudioFile: i,
})
}}
>
{item.label}
</span>
</li>
))
}
</ul>
</div>
)
}
希望对您有帮助。