qui*_*bit 5 javascript audio reactjs
我有一个 React 组件,可以在您单击按钮时播放/暂停音频。它工作得很好,我一次在一个页面上渲染了大约 5 个。但是,如果您单击一个播放,然后单击另一个播放,两个音频都在播放,这不是很好。这是我的组件代码:
import React from 'react';
import playIcon from './images/play.png';
import pauseIcon from './images/pause.png';
class Music extends React.Component {
constructor(props) {
super(props);
this.state = { 'play': false };
this.url = props.src;
this.audio = new Audio(this.url);
this.audio.preload = 'none';
this.togglePlay = this.togglePlay.bind(this);
}
togglePlay() {
this.setState({'play': !this.state.play}, () => {
this.state.play ? this.audio.play() : this.audio.pause();
});
}
componentWillUnmount () {
this.audio.pause();
}
render() {
return (
<div style={this.props.style} className={this.props.className}>
{this.state.play
? <button className="audio-button" aria-label="Pause" onClick={this.togglePlay}><img src={pauseIcon} width="34" height="34" alt="Pause"></img></button>
: <button className="audio-button" aria-label="Play" onClick={this.togglePlay}><img src={playIcon} width="34" height="34" alt="Play"></img></button>}
</div>
);
}
}
export default Music;
Run Code Online (Sandbox Code Playgroud)
我已经环顾四周,一个潜在的解决方案是使用 redux 或其他一些状态管理库。我想避免这种情况,否则我在本网站中不需要它。我已经研究了事件侦听器(即此处提出的解决方案),但是当我执行 a 时,document.getElementsByTagName('audio')我会返回一个空的HTMLCollection. 这个解决方案更接近,但我无法弥合它在 jQuery 中的实现与我在 React 中使用的实现之间的差距。
有没有办法识别正在播放的音频并在播放新音频之前从 React 组件暂停它?任何和所有建议表示赞赏。
从马学政和 TheIncorrigible1 那里得到了一些重要的提示。基本上将音频移动到它自己的模块中。play方法pause从其中导出,并currentlyPlaying在该模块中进行跟踪。
我调整我的Music组件看起来像这样
import React from 'react';
import playIcon from './images/play.png';
import pauseIcon from './images/pause.png';
import globalAudio from './globalAudio';
class Music extends React.Component {
constructor(props) {
super(props);
this.state = { 'play': false };
this.name = props.src;
this.togglePlay = this.togglePlay.bind(this);
}
togglePlay() {
this.setState({'play': !this.state.play}, () => {
this.state.play ? globalAudio.play(this.name) : globalAudio.pause(this.name);
});
}
componentWillUnmount () {
globalAudio.pause(this.name);
}
render() {
return (
<div style={this.props.style} className={this.props.className}>
{this.state.play
? <button className="audio-button" aria-label="Pause" onClick={this.togglePlay}><img src={pauseIcon} width="34" height="34" alt="Pause"></img></button>
: <button className="audio-button" aria-label="Play" onClick={this.togglePlay}><img src={playIcon} width="34" height="34" alt="Play"></img></button>}
</div>
);
}
}
export default Music;
Run Code Online (Sandbox Code Playgroud)
我的新模块globalAudio:
import audio1 from './audio1.mp3';
import audio2 from './audio2.mp3';
import audio3 from './audio3.mp3';
import audio4 from './audio4.mp3';
import audio5 from './audio5.mp3';
const audios = {
'audio1': new Audio(audio1),
'audio2': new Audio(audio2),
'audio3': new Audio(audio3),
'audio4': new Audio(audio4),
'audio5': new Audio(audio5)
};
let currentlyPlaying = null;
const play = (name) => {
if (currentlyPlaying) {
audios[currentlyPlaying].pause();
}
audios[name].play();
currentlyPlaying = name;
};
const pause = (name) => {
currentlyPlaying = null;
audios[name].pause();
};
export default {
pause,
play
};
Run Code Online (Sandbox Code Playgroud)
感谢所有的建议,它们都非常有帮助。
| 归档时间: |
|
| 查看次数: |
2929 次 |
| 最近记录: |