vue使用H5的audio標(biāo)簽問題
使用H5的audio標(biāo)簽
template代碼:
<audio ref="audio" :src="audioUrl"></audio>
data里綁定audioUrl為audio的路徑
audioUrl: 'static/audio/notify.wav' // 聲音源
按鈕播放聲音:
click () {
? ? this.$refs.audio.play()
}vue中自定義audio
一個(gè)頁面上創(chuàng)建很多audio標(biāo)簽 并且自定義樣式播放。

首先創(chuàng)建可以增刪的播放列表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數(shù)據(jù)
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);
},然后點(diǎn)擊播放、暫停、 監(jiān)聽音頻當(dāng)前時(shí)間以及播放完畢
//播放音頻
playAudio(index){
let _this =this;
let audioMedia = this.$refs.audioMedia;//獲取所有audio對象
this.audioList[this.playAudioIndex].isplay = false;//上一個(gè)播放的audio圖片換為暫停
audioMedia[this.playAudioIndex].pause();//上一個(gè)播放的audio暫停
this.audioList[index].isplay = true;//把當(dāng)前audio圖片設(shè)置為播放狀態(tài)
//當(dāng)前audio延時(shí)播放--此處處理是由于updateTime在獲取當(dāng)前播放時(shí)長時(shí),會獲取一次上個(gè)audio的播放時(shí)長,才能獲取到當(dāng)前時(shí)長,頁面播放進(jìn)度會跳一下
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();
},
//音頻監(jiān)測當(dāng)前時(shí)間
updateTime(e){
let _this = this;
// _this.$set(_this.audioList[_this.playAudioIndex],"play_live",_this.audioList[_this.playAudioIndex].play_live);
//用秒數(shù)來顯示當(dāng)前播放進(jìn)度
// console.log(e.target.currentTime)
let timeDisplay = Math.floor(e.target.currentTime);//獲取實(shí)時(shí)時(shí)間
_this.$set(_this.audioList[_this.playAudioIndex],"play_live",timeDisplay);
},
//音頻監(jiān)測播放完畢
end(e){
console.log(e)
this.audioList[this.playAudioIndex].isplay = false;
},實(shí)現(xiàn)了播放之后,再處理點(diǎn)擊播放
這里注意的e.clientX offsetLeft e.target.offsetLeft

//點(diǎn)擊的是未拖動(dòng)過進(jìn)度的進(jìn)度條
mousedown(e,index){
let audioMedia = this.$refs.audioMedia;
//父級
let fdrag = document.getElementsByClassName("d_andio_wrap")[0];
//點(diǎn)擊時(shí)離左邊框距離 e.clientX點(diǎn)擊的那個(gè)點(diǎn)離瀏覽器左邊距 fdrag.offsetLeft父級離瀏覽器距離 e.target.offsetLeft事件源離父級左邊框距離
let targetLeft = e.clientX-fdrag.offsetLeft-e.target.offsetLeft;
//獲取事件源的寬度
let targetWidth = e.target.offsetWidth;
//根據(jù)百分比轉(zhuǎn)化成音頻想要的秒數(shù)
let play_live = Math.floor((targetLeft/targetWidth)*this.audioList[index].play_time);
// console.log(targetLeft,targetWidth);
this.audioList[index].play_live = play_live;
//判斷播放狀態(tài)時(shí)直接跳轉(zhuǎn)播放
if(!audioMedia[index].paused){
// console.log('播放')
audioMedia[index].currentTime = play_live;
}
},
//點(diǎn)擊已經(jīng)播放的進(jìn)度條 但是要使用class = audio_progress的寬度以及距左邊的距離
mousedownP(e,index){
let audioMedia = this.$refs.audioMedia;
//父級
let fdrag = document.getElementsByClassName("d_andio_wrap")[0];
//進(jìn)度條底色的總長度作為進(jìn)度條總寬度
let zdrag = document.getElementsByClassName("audio_progress")[0];
//點(diǎn)擊時(shí)離左邊框距離 e.clientX點(diǎn)擊的那個(gè)點(diǎn)離瀏覽器左邊距 fdrag.offsetLeft父級離瀏覽器距離 zdrag.offsetLeft事件源離父級左邊框距離
let targetLeft = e.clientX-fdrag.offsetLeft-zdrag.offsetLeft;
//獲取事件源的寬度
let targetWidth = zdrag.offsetWidth;
//根據(jù)百分比轉(zhuǎn)化成音頻想要的秒數(shù)
let play_live = Math.floor((targetLeft/targetWidth)*this.audioList[index].play_time);
// console.log(play_live);
this.audioList[index].play_live = play_live;
//判斷播放狀態(tài)時(shí)直接跳轉(zhuǎn)播放
if(!audioMedia[index].paused){
// console.log('播放')
audioMedia[index].currentTime = play_live;
}
},
拖動(dòng)進(jìn)度條
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];
//獲取事件源的寬度 這里是因?yàn)閳A點(diǎn)的寬度為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 鼠標(biāo)離瀏覽器邊框的距離 drag.offsetLeft鼠標(biāo)離事件源左邊框距離
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;//移動(dòng)時(shí)的距離
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();
}
//判斷播放狀態(tài)時(shí)直接跳轉(zhuǎn)播放
if(!audioMedia[elementIndex].paused){
// console.log('播放')
audioMedia[elementIndex].currentTime = play_live;
}
};
};
},
小結(jié):同一個(gè)頁面如果只創(chuàng)建一個(gè)audio時(shí),也可以實(shí)現(xiàn)切換src進(jìn)行播放,但是在跳轉(zhuǎn)時(shí)間點(diǎn)播放時(shí)失效,可能的原因是在切換src后,音頻沒有緩存,導(dǎo)致從0開始播放了。
在點(diǎn)擊跳轉(zhuǎn)時(shí),點(diǎn)擊進(jìn)度條上面時(shí)要注意事件源的不同,從而導(dǎo)致獲取的距瀏覽器距離已經(jīng)距左邊框距離的錯(cuò)誤。
總結(jié)
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
Element-ui中元素滾動(dòng)時(shí)el-option超出元素區(qū)域的問題
這篇文章主要介紹了Element-ui中元素滾動(dòng)時(shí)el-option超出元素區(qū)域的問題,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2019-05-05
詳解本地Vue項(xiàng)目請求本地Node.js服務(wù)器的配置方法
本文只針對自己需要本地模擬接口于是搭建一個(gè)本地node服務(wù)器供自己測試使用,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2022-03-03
在vue中使用css modules替代scroped的方法
本篇文章主要介紹了在vue中使用css modules替代scroped的方法,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2018-03-03
vue設(shè)置必填項(xiàng)和判斷必填項(xiàng)是否填入的彈窗提示
表格判斷在很多項(xiàng)目中都用得到,本文主要介紹了vue設(shè)置必填項(xiàng)和判斷必填項(xiàng)是否填入的彈窗提示,具有一定的參考價(jià)值,感興趣的可以了解一下2023-11-11
vue子路由跳轉(zhuǎn)實(shí)現(xiàn)tab選項(xiàng)卡效果
這篇文章主要為大家詳細(xì)介紹了vue子路由跳轉(zhuǎn)實(shí)現(xiàn)tab選項(xiàng)卡效果,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-03-03
Vue的移動(dòng)端多圖上傳插件vue-easy-uploader的示例代碼
這篇文章主要介紹了Vue的移動(dòng)端多圖上傳插件vue-easy-uploader的示例代碼,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2017-11-11
原生JS?Intersection?Observer?API實(shí)現(xiàn)懶加載
這篇文章主要為大家介紹了原生JS?Intersection?Observer?API實(shí)現(xiàn)懶加載示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-07-07
Vue中import與@import的區(qū)別及使用場景說明
這篇文章主要介紹了Vue中import與@import的區(qū)別及使用場景說明,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-06-06
vue.config.js中配置configureWebpack和chainWebpack以及一些常用的配置
configureWebpack和chainWebpack都是Vue CLI中用于修改Webpack配置的工具,configureWebpack可以通過對象或函數(shù)修改配置,簡單直接;chainWebpack則使用WebpackChainAPI,適合復(fù)雜配置,兩者可以結(jié)合使用,以達(dá)到更精細(xì)的配置需求,幫助開發(fā)者優(yōu)化項(xiàng)目構(gòu)建2024-10-10

