Javascript 使用<;音频>;在React应用程序中标记,单击播放所选文件
我可以通过数组映射并渲染一些图像(在generateWord函数的底部附近)。我希望能够点击图像,播放相关的音频文件。它播放阵列中的第二个(或最后一个)音频文件。我想我应该在音频文件上附加一些键或索引,以便它知道播放哪一个,但我不确定如何准确播放。下面的代码是组件。部分状态会在其下方注释,以便您可以查看映射数组的来源Javascript 使用<;音频>;在React应用程序中标记,单击播放所选文件,javascript,reactjs,audio,onclick,state,Javascript,Reactjs,Audio,Onclick,State,我可以通过数组映射并渲染一些图像(在generateWord函数的底部附近)。我希望能够点击图像,播放相关的音频文件。它播放阵列中的第二个(或最后一个)音频文件。我想我应该在音频文件上附加一些键或索引,以便它知道播放哪一个,但我不确定如何准确播放。下面的代码是组件。部分状态会在其下方注释,以便您可以查看映射数组的来源 const debug = require("debug")("components:Displayletter") const React = require("react")
const debug = require("debug")("components:Displayletter")
const React = require("react")
const { connect } = require("react-redux")
const request = require("superagent")
const { Link } = require("react-router")
class Displayletter extends React.Component {
constructor() {
super()
this.playSound = this.playSound.bind(this)
}
playSound() {
this.playWord.play()
}
handleClick(e) {
e.preventDefault()
this.props.router.push("/")
}
render() {
debug(this.props)
const { dispatch, letters, letter } = this.props
const wordsArr = letter.wordImage
return (
<div className="row letter-container">
<div className="col-sm-12">
{this.generateWord(wordsArr)}
</div>
</div>
)
}
generateWord(wordsArr) {
return wordsArr.map((word) => {
return (
<div>
<audio
key={word.sound}
ref={(x) => { this.playWord = x; }}>
<source src={word.sound} preload='auto'/>
</audio>
<img src={word.image} onClick={this.playSound} />
</div>
)
})
}
}
module.exports = connect(state => state)(Displayletter)
//STATE
// letters: [
// {
// id: 1,
// capital: "A",
// lowercase: "a",
// capitalSound: "/sounds/capitalSounds/A.mp3",
// lowerSound: "/sounds/lowerSounds/a.mp3",
// wordImage: [
// {id:1, image:"images/words/aniwaniwa.png", sound: "sounds/ua.mp3"},
// {id:2, image:"images/words/anuhe.png", sound: "sounds/anuhe.mp3"},
// ],
// multimedia: "/multimedia/aniwaniwa.webm",
// mediaName: "Aniwaniwa Song",
// },
const debug=require(“调试”)(“组件:Displayletter”)
const React=require(“React”)
const{connect}=require(“react redux”)
const request=require(“超级代理”)
const{Link}=require(“反应路由器”)
类Displayletter扩展了React.Component{
构造函数(){
超级()
this.playSound=this.playSound.bind(this)
}
播放声音(){
这个。playWord。play()
}
handleClick(e){
e、 预防默认值()
此.props.router.push(“/”)
}
render(){
调试(this.props)
const{dispatch,letters,letter}=this.props
const wordsArr=letter.wordImage
返回(
{this.generateWord(wordsArr)}
)
}
generateWord(wordsArr){
返回单词sr.map((单词)=>{
返回(
{this.playWord=x;}}>
)
})
}
}
module.exports=connect(状态=>state)(显示字母)
//陈述
//信件:[
// {
//id:1,
//大写:“A”,
//小写:“a”,
//capitalSound:“/sounds/capitalSounds/A.mp3”,
//lowerSound:“/sounds/lowerSounds/a.mp3”,
//wordImage:[
//{id:1,图片:“images/words/aniwaniwa.png”,声音:“sounds/ua.mp3”},
//{id:2,图像:“images/words/anuhe.png”,声音:“sounds/anuhe.mp3”},
// ],
//多媒体:“/multimedia/aniwaniwa.webm”,
//mediaName:“Aniwaniwa歌曲”,
// },
第二次迭代-在构造函数中添加了一个空对象,并通过onClick和playSound传递了一个“word”参数
generateWord(wordsArr) {
return wordsArr.map((word) => {
return (
<div>
<audio
key={word}
ref={(x) => { this.playWords[word] = x; }}>
<source src={word.sound} preload='auto'/>
</audio>
<img src={word.image} onClick={this.playSound.bind(this, word)} />
</div>
)
})
playSound(word) {
this.playWords[word].play()
}
constructor() {
super()
this.playCapital = this.playCapital.bind(this)
this.playLower = this.playLower.bind(this)
this.playSound = this.playSound.bind(this)
this.playWords = {}
}
generateWord(wordsArr){
返回单词sr.map((单词)=>{
返回(
{this.playWords[word]=x;}}>
)
})
播放声音(word){
这个.playWords[word].play()
}
构造函数(){
超级()
this.playCapital=this.playCapital.bind(this)
this.playLower=this.playLower.bind(this)
this.playSound=this.playSound.bind(this)
this.playWords={}
}
***************第三轮*******************
const debug = require("debug")("components:Displayletter")
const React = require("react")
const { connect } = require("react-redux")
const request = require("superagent")
const { Link } = require("react-router")
class Displayletter extends React.Component {
constructor() {
super()
this.playCapital = this.playCapital.bind(this)
this.playLower = this.playLower.bind(this)
this.playWords = {}
}
playCapital() {
this.playCap.play()
}
playLower() {
this.playLow.play()
}
playSound(word) {
this.playWords[word].play()
}
handleClick(e) {
e.preventDefault()
this.props.router.push("/")
}
render() {
debug(this.props)
const { dispatch, letters, letter } = this.props
const wordsArr = letter.wordImage
return (
<div className="row letter-container">
<div className="col-sm-12">
<audio
key={letter.capitalSound}
ref={(cap) => { this.playCap = cap; }}>
<source
src={letter.capitalSound}
preload="auto" />
<track
kind="captions"
src=""
srcLang="en" />
</audio>
<audio
key={letter.lowerSound}
ref={(low) => { this.playLow = low; }}>
<source
src={letter.lowerSound}
preload="auto" />
<track
kind="captions"
src=""
srcLang="en" />
</audio>
<button
type="button"
className="btn btn-xl display"
onClick={this.playCapital}>
{letter.capital}
</button>
<button
type="button"
className="btn btn-xl display"
onClick={this.playLower}>
{letter.lowercase}
</button>
</div>
<div className="col-sm-12">
{this.generateWord(wordsArr)}
</div>
<div className="col-sm-12">
<Link key={letter.id} to={`/media/${letter.capital}`}>
<button
type="button"
className="btn"
onClick={() =>
dispatch({
type: "RENDER_LETTER",
payload: letter,
})
}>
Watch: {letter.mediaName}
</button>
</Link>
</div>
</div>
)
}
generateWord(wordsArr) {
return wordsArr.map((word) => {
return (
<div>
<audio
key={word}
ref={(x) => { this.playWords[word] = x; }}>
<source src={word.sound} preload='auto'/>
</audio>
<img src={word.image} onClick={this.playSound.bind(this, word)} />
</div>
)
})
}
}
module.exports = connect(state => state)(Displayletter)
// letters: [
// {
// id: 1,
// capital: "A",
// lowercase: "a",
// capitalSound: "/sounds/capitalSounds/A.mp3",
// lowerSound: "/sounds/lowerSounds/a.mp3",
// wordImage: [
// {id:1, image:"images/words/aniwaniwa.png", sound: "sounds/ua.mp3"},
// {id:2, image:"images/words/anuhe.png", sound: "sounds/anuhe.mp3"},
// ],
// multimedia: "/multimedia/aniwaniwa.webm",
// mediaName: "Aniwaniwa Song",
// },
const debug=require(“调试”)(“组件:Displayletter”)
const React=require(“React”)
const{connect}=require(“react redux”)
const request=require(“超级代理”)
const{Link}=require(“反应路由器”)
类Displayletter扩展了React.Component{
构造函数(){
超级()
this.playCapital=this.playCapital.bind(this)
this.playLower=this.playLower.bind(this)
this.playWords={}
}
playCapital(){
这个。playCap。play()
}
playLower(){
这个。playLow。play()
}
播放声音(word){
这个.playWords[word].play()
}
handleClick(e){
e、 预防默认值()
此.props.router.push(“/”)
}
render(){
调试(this.props)
const{dispatch,letters,letter}=this.props
const wordsArr=letter.wordImage
返回(
{this.playCap=cap;}}>
{this.playLow=low;}}>
{字母大写}
{字母.小写}
{this.generateWord(wordsArr)}
派遣({
键入:“呈现字母”,
有效载荷:字母,
})
}>
注意:{letter.mediaName}
)
}
generateWord(wordsArr){
返回单词sr.map((单词)=>{
返回(
{this.playWords[word]=x;}}>
)
})
}
}
module.exports=connect(状态=>state)(显示字母)
//信件:[
// {
//id:1,
//大写:“A”,
//小写:“a”,
//capitalSound:“/sounds/capitalSounds/A.mp3”,
//lowerSound:“/sounds/lowerSounds/a.mp3”,
//wordImage:[
//{id:1,图片:“images/words/aniwaniwa.png”,声音:“sounds/ua.mp3”},
//{id:2,图像:“images/words/anuhe.png”,声音:“sounds/anuhe.mp3”},
// ],
//多媒体:“/multimedia/aniwaniwa.webm”,
//mediaName:“Aniwaniwa歌曲”,
// },
您实际上非常接近!问题在于如何保存对音频元素的引用:ref={(x)=>{this.playWord=x;}
。请注意,由于这是在映射中,所以每个元素都会一个接一个地保存自己,作为this.playWord
,因此,为什么单击时只播放最后一个文件
相反,您要做的是将所有单词保存到一个对象或数组中,然后在单击处理程序中引用要播放的单词
首先,在构造函数中执行类似于this.playWords={}
的操作,然后在render
中执行ref={(x)=>{this.playWords[word]=x;}}
操作。这将为您提供一个对象playWords
,该对象存储对word键入的所有音频元素的引用
然后,给playSound
一个word参数,并确保onClick通过像onClick={this.playSound.bind(this,word)}
一样绑定它来传入该参数
我已经准备了一个简单的示例来演示这个基本结构;您应该能够轻松地将这些原则应用到您的组件中
类示例扩展了React.Component{
构造函数(){
超级();
this.words={};
}
日志点击(一){
log(“用户点击”,此.words[i]);
}
render(){
const wordsArr=“这是一个示例句子”。拆分(“”);
返回(