前言
一开始看到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>
文章到这里就完结了,如果对你有帮忙,欢送点赞,珍藏,谢谢~