vue中自定义audio
audio在一个页面上可以创建n个audio标签(可以移除和增加),点击时可以触发其中的一个播放,其他暂停,并且不管是暂停还是播放状态都可以点击任意位置进行播放。样式是这样的![](https://img-blog.csdnimg.cn/20200427180045107.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,sh..
·
一个页面上创建很多audio标签 并且自定义样式播放。
首先创建可以增删的播放列表css就不再显示了
<div class="d_andio_wrap">
<div class="d_audio" v-for="(item,index) in audioList" :key="index">
<audio id="audioMedia" :src="item.src" @timeupdate="updateTime" ref='audioMedia' @ended="end"></audio>
<img v-if="!item.isplay" class="img" src="../../../assets/images/icon_play.png" alt="" @click="playAudio(index)">
<img v-if="item.isplay" class="img" src="../../../assets/images/icon_pause.png" alt="" @click="pauseAudio(index)">
<div class="audio_body">
<div class="audio_title">
<span>{{item.title}}</span>
</div>
<div class="audio_info">
<span class="audio_live">{{item.play_live | audioTime}}</span>
<div class="audio_progress" @mousedown.self="mousedown($event,index)">
<div class="audio_progress_line" :style="{width:item.play_live/item.play_time*100+'%'}" @mousedown.self="mousedownP($event,index)"></div>
<div class="audio_progress_dot" :style="{left:item.play_live/item.play_time*100+'%'}" @mousedown.self="drag('audio_progress_dot',index)"></div>
</div>
<span class="audio_live">{{item.play_time | audioTime}}</span>
</div>
</div>
<i class="el-icon-error" @click="deleteAudio(index)"></i>
</div>
</div>
data数据
audioList:[
{
title:'龙的传人',
key:0,
videoid:'',
src:"ssssss.mp3",
play_live:0,
play_time:'154',
isplay:false,//是否播放
},
{
title:'龙的传人',
key:0,
videoid:'',
src:"sssssss.mp3",
play_live:0,
play_time:'154',
isplay:false,//是否播放
}
],
删除音频,增加音频就不再写了
//删除音频
deleteAudio(index){
this.audioList.splice(index, 1);
},
然后点击播放、暂停、 监听音频当前时间以及播放完毕
//播放音频
playAudio(index){
let _this =this;
let audioMedia = this.$refs.audioMedia;//获取所有audio对象
this.audioList[this.playAudioIndex].isplay = false;//上一个播放的audio图片换为暂停
audioMedia[this.playAudioIndex].pause();//上一个播放的audio暂停
this.audioList[index].isplay = true;//把当前audio图片设置为播放状态
//当前audio延时播放--此处处理是由于updateTime在获取当前播放时长时,会获取一次上个audio的播放时长,才能获取到当前时长,页面播放进度会跳一下
setTimeout(()=>{
audioMedia[index].currentTime = this.audioList[index].play_live;
audioMedia[index].play();
_this.playAudioIndex = index;
},100)
// console.log(this.audioList[index].play_live)
},
//暂停音频
pauseAudio(index){
let audioMedia = this.$refs.audioMedia;
this.audioList[index].isplay = false;
audioMedia[index].pause();
},
//音频监测当前时间
updateTime(e){
let _this = this;
// _this.$set(_this.audioList[_this.playAudioIndex],"play_live",_this.audioList[_this.playAudioIndex].play_live);
//用秒数来显示当前播放进度
// console.log(e.target.currentTime)
let timeDisplay = Math.floor(e.target.currentTime);//获取实时时间
_this.$set(_this.audioList[_this.playAudioIndex],"play_live",timeDisplay);
},
//音频监测播放完毕
end(e){
console.log(e)
this.audioList[this.playAudioIndex].isplay = false;
},
实现了播放之后,再处理点击播放
这里注意的e.clientX offsetLeft e.target.offsetLeft
//点击的是未拖动过进度的进度条
mousedown(e,index){
let audioMedia = this.$refs.audioMedia;
//父级
let fdrag = document.getElementsByClassName("d_andio_wrap")[0];
//点击时离左边框距离 e.clientX点击的那个点离浏览器左边距 fdrag.offsetLeft父级离浏览器距离 e.target.offsetLeft事件源离父级左边框距离
let targetLeft = e.clientX-fdrag.offsetLeft-e.target.offsetLeft;
//获取事件源的宽度
let targetWidth = e.target.offsetWidth;
//根据百分比转化成音频想要的秒数
let play_live = Math.floor((targetLeft/targetWidth)*this.audioList[index].play_time);
// console.log(targetLeft,targetWidth);
this.audioList[index].play_live = play_live;
//判断播放状态时直接跳转播放
if(!audioMedia[index].paused){
// console.log('播放')
audioMedia[index].currentTime = play_live;
}
},
//点击已经播放的进度条 但是要使用class = audio_progress的宽度以及距左边的距离
mousedownP(e,index){
let audioMedia = this.$refs.audioMedia;
//父级
let fdrag = document.getElementsByClassName("d_andio_wrap")[0];
//进度条底色的总长度作为进度条总宽度
let zdrag = document.getElementsByClassName("audio_progress")[0];
//点击时离左边框距离 e.clientX点击的那个点离浏览器左边距 fdrag.offsetLeft父级离浏览器距离 zdrag.offsetLeft事件源离父级左边框距离
let targetLeft = e.clientX-fdrag.offsetLeft-zdrag.offsetLeft;
//获取事件源的宽度
let targetWidth = zdrag.offsetWidth;
//根据百分比转化成音频想要的秒数
let play_live = Math.floor((targetLeft/targetWidth)*this.audioList[index].play_time);
// console.log(play_live);
this.audioList[index].play_live = play_live;
//判断播放状态时直接跳转播放
if(!audioMedia[index].paused){
// console.log('播放')
audioMedia[index].currentTime = play_live;
}
},
拖动进度条
drag(element,index) {
let elementIndex = index;
let audioMedia = this.$refs.audioMedia;
//事件源
let _this = this;
let drag = document.getElementsByClassName(element)[index];
let dragOffsetLeft = drag.offsetLeft;
//父级容器的宽高 -- 避免在容器外拖拽
let fdrag = document.getElementsByClassName("audio_progress")[index];
//获取事件源的宽度 这里是因为圆点的宽度为drag.offsetWidth 不减去本身宽度不能够精确地表示出音频长短 也可以在moveX 加上drag.offsetWidth
let fdragWidth = fdrag.offsetWidth - drag.offsetWidth;
let diffX;//fdrag离浏览器左边的固定距离
let diffY;
let play_live;
drag.onmousedown = function(event) {
let e = event || window.event;
//e.clientX 鼠标离浏览器边框的距离 drag.offsetLeft鼠标离事件源左边框距离
e.preventDefault();
diffX = e.clientX - drag.offsetLeft;
if (typeof drag.setCapture !== "undefined") {
drag.setCapture();
}
document.onmousemove = function(event) {
let e = event || window.event;
let moveX = e.clientX - diffX;//移动时的距离
if (moveX <= 0) {
moveX = 0;
} else if (moveX > fdrag.offsetWidth - drag.offsetWidth) {
moveX = fdrag.offsetWidth - drag.offsetWidth;
}
play_live = Math.floor((moveX/fdragWidth)*_this.audioList[elementIndex].play_time);
_this.audioList[elementIndex].play_live = play_live;
};
document.onmouseup = function(event) {
this.onmousemove = null;
this.onmouseup = null;
if (typeof drag.setCapture !== "undefined") {
drag.setCapture();
}
//判断播放状态时直接跳转播放
if(!audioMedia[elementIndex].paused){
// console.log('播放')
audioMedia[elementIndex].currentTime = play_live;
}
};
};
},
总结:
同一个页面如果只创建一个audio时,也可以实现切换src进行播放,但是在跳转时间点播放时失效,可能的原因是在切换src后,音频没有缓存,导致从0开始播放了。
在点击跳转时,点击进度条上面时要注意事件源的不同,从而导致获取的距浏览器距离已经距左边框距离的错误。
如果有错误之处,希望大佬们指出。
更多推荐
已为社区贡献1条内容
所有评论(0)