共计 6185 个字符,预计需要花费 16 分钟才能阅读完成。
前言
一开始看到 UI 设计稿,我心田是非常抗拒的。感觉用原生 audio
的款式就能够了,也不是特地丑,毕竟工夫给的不多,自定义款式还要改逻辑啥的。在网上搜寻了一番有没有适合的插件,没有看到心动的。最初还是硬着头皮本人写了。
参考了一个博客,很感激这位博主,逻辑都能够用。不过原博用的 jquery,我本人用 vue,而且我的页面可能有不止一个 audio,设计稿和原博也很不一样,所以改代码还是花了一番心理。
参考链接:音频(audio)自定义款式以及管制操作面板
vue 版本:2.6.12
我这里是依照我的设计稿做进去的样子,如果你的设计稿跟我的不一样,那也只须要改一下 css 局部和 html,js 还是能间接套用的。
如果急用的同学能够间接跳到最初看残缺的代码,复制了不出意外能够间接用的,只须要把播放按钮的图片改成你本人的图片,再增加可用的 audio 链接就能够了。
html 代码:
<div class="page-container">
<div v-for="(item, index) in content" :key="index" class="list-box">
<audio ref="audio" :src="item.audio_url" controls @loadedmetadata="fillTime($event, index)"
@timeupdate.stop="updateProgress(index)" @ended.stop="audioEnded(index)">
</audio>
<!-- 音频名字 -->
<div class="audio-name">{{item.audio_name}}</div>
<div class="control-row">
<!-- 管制播放暂停的按钮 -->
<img src="@/assets/play.png" class="play-icon" alt=""@click="playAudio(index)">
<div class="row-right">
<!-- 进度条 -->
<div class="pgs">
<div class="pgs-play"></div>
</div>
<!-- 以后播放时长和总时长 -->
<div class="time-row">
<span class="played-time">{{audioArr[index].currentTime }}</span>
<span class="audio-time">{{audioArr[index].duration }}</span>
</div>
</div>
</div>
</div>
</div>
js 代码:
export default {data() {
return {audioNodes: [], // 用于寄存所有 audio 的 DOM 节点
audioArr: [], // 用于保护 audio 的总时长和以后播放工夫的数组
content: [ // 寄存 audio 的地址信息,个别是接口返回
{"audio_name":"20210112_1056.m4a","audio_url":"https://xxx.com/android1610420451567524.m4a"},
{"audio_name":"20210112_1056.m4a","audio_url":"https://xxx.com/android1610420451567524.m4a"},
]
}
},
mounted() {this.audioNodes = document.getElementsByClassName('list-box')
this.content.forEach((item, index) => {this.$set(this.audioArr, index, { duration: '', currentTime:'00:00'})
})
},
methods: {
// 切换播放,暂停按钮的事件
playAudio(index) {let audio = this.audioNodes[index].firstChild
if (audio.paused) {audio.play()
} else {audio.pause()
}
},
// 获取音频的总时长
fillTime(event, index) {this.audioArr[index].duration = this.transTime(event.target.duration)
},
// 将秒数转化成 (分: 秒) 格局
transTime(time) {let duration = parseInt(time)
let minute = parseInt(duration / 60).toString().padStart(2, '0')
let sec = (duration % 60).toString().padStart(2, '0')
return `${minute}:${sec}`
},
// 进度条播放的事件
updateProgress(index) {let audio = this.audioNodes[index].firstChild
let value = Math.round((Math.floor(audio.currentTime) / Math.floor(audio.duration)) * 100, 0)
this.audioArr[index].currentTime = this.transTime(audio.currentTime)
let progressTag = this.audioNodes[index].getElementsByClassName('pgs-play')[0]
progressTag.style.left = `${value}%`
},
// 播放完结的解决动作
audioEnded(index) {let audio = this.audioNodes[index].firstChild
audio.currentTime = 0
audio.pause()},
}
}
css 代码:
.pgs {
background-color: #D8D4D1;
text-align: center;
position: relative;
height: 2px;
margin-bottom: 10px;
}
.pgs-play {
position: absolute;
top: -2.5px;
left: 0;
width: 7px;
height: 7px;
border-radius: 50%;
background-color: #B03F28;
z-index: 1;
}
.play-icon {
width: 45px;
height: 45px;
margin-right: 15px;
}
audio {
display: block;
height: 0;
}
.audio-box {
background: #F5F5F5;
border: 1px solid #D8D4D1;
border-radius: 5px;
width: 100%;
padding: 15px 12px;
box-sizing: border-box;
}
.audio-name {
font-size: 15px;
color: #252120;
margin-bottom: 15px;
overflow:hidden; // 超出的文本暗藏
text-overflow:ellipsis; // 溢出用省略号显示
white-space:nowrap; // 溢出不换行
}
.control-row {
display: flex;
align-items: flex-end;
}
.row-right {flex-grow: 100;}
.time-row {
position: relative;
color: #B0AFAD;
font-size: 12px;
margin-bottom: 3px;
}
.audio-time {
position: absolute;
right: 0;
}
残缺代码(audio.vue)
- 能够间接套用,只须要改 control-row 外面的图片地址,这是播放按钮的图片。
<style lang="scss">
.page-container {
.pgs {
background-color: #D8D4D1;
text-align: center;
position: relative;
height: 2px;
margin-bottom: 10px;
}
.pgs-play {
position: absolute;
top: -2.5px;
left: 0;
width: 7px;
height: 7px;
border-radius: 50%;
background-color: #B03F28;
z-index: 1;
}
.play-icon {
width: 45px;
height: 45px;
margin-right: 15px;
}
audio {
display: block;
height: 0;
}
.audio-box {
background: #F5F5F5;
border: 1px solid #D8D4D1;
border-radius: 5px;
width: 100%;
padding: 15px 12px;
box-sizing: border-box;
}
.audio-name {
font-size: 15px;
color: #252120;
margin-bottom: 15px;
overflow: hidden; // 超出的文本暗藏
text-overflow: ellipsis; // 溢出用省略号显示
white-space: nowrap; // 溢出不换行
}
.control-row {
display: flex;
align-items: flex-end;
}
.row-right {flex-grow: 100;}
.time-row {
position: relative;
color: #B0AFAD;
font-size: 12px;
margin-bottom: 3px;
}
.audio-time {
position: absolute;
right: 0;
}
}
</style>
<template>
<div class="page-container">
<div v-for="(item, index) in content" :key="index" class="list-box">
<audio ref="audio" :src="item.audio_url" controls @loadedmetadata="fillTime($event, index)"
@timeupdate.stop="updateProgress(index)" @ended.stop="audioEnded(index)">
</audio>
<!-- 音频名字 -->
<div class="audio-name">{{item.audio_name}}</div>
<div class="control-row">
<!-- 管制播放暂停的按钮 -->
<img src="@/assets/play.png" class="play-icon" alt=""@click="playAudio(index)">
<div class="row-right">
<!-- 进度条 -->
<div class="pgs">
<div class="pgs-play"></div>
</div>
<!-- 以后播放时长和总时长 -->
<div class="time-row">
<span class="played-time">{{audioArr[index].currentTime }}</span>
<span class="audio-time">{{audioArr[index].duration }}</span>
</div>
</div>
</div>
</div>
</div>
</template>
<script>
export default {data() {
return {audioNodes: [], // 用于寄存所有 audio 的 DOM 节点
audioArr: [], // 用于保护 audio 的总时长和以后播放工夫的数组
content: [ // 寄存 audio 的地址信息,个别是接口返回
{"audio_name":"20210112_1056.m4a","audio_url":"https://xxx.com/android1610420451567524.m4a"},
{"audio_name":"20210112_1056.m4a","audio_url":"https://xxx.com/android1610420451567524.m4a"},
]
}
},
mounted() {this.audioNodes = document.getElementsByClassName('list-box')
this.content.forEach((item, index) => {this.$set(this.audioArr, index, { duration: '', currentTime:'00:00'})
})
},
methods: {
// 切换播放,暂停按钮的事件
playAudio(index) {let audio = this.audioNodes[index].firstChild
if (audio.paused) {audio.play()
} else {audio.pause()
}
},
// 获取音频的总时长
fillTime(event, index) {this.audioArr[index].duration = this.transTime(event.target.duration)
},
// 将秒数转化成 (分: 秒) 格局
transTime(time) {let duration = parseInt(time)
let minute = parseInt(duration / 60).toString().padStart(2, '0')
let sec = (duration % 60).toString().padStart(2, '0')
return `${minute}:${sec}`
},
// 进度条播放的事件
updateProgress(index) {let audio = this.audioNodes[index].firstChild
let value = Math.round((Math.floor(audio.currentTime) / Math.floor(audio.duration)) * 100, 0)
this.audioArr[index].currentTime = this.transTime(audio.currentTime)
let progressTag = this.audioNodes[index].getElementsByClassName('pgs-play')[0]
progressTag.style.left = `${value}%`
},
// 播放完结的解决动作
audioEnded(index) {let audio = this.audioNodes[index].firstChild
audio.currentTime = 0
audio.pause()},
}
}
</script>
文章到这里就完结了,如果对你有帮忙,欢送点赞,珍藏,谢谢~
正文完