分享站又有新功能了:將文件站上的語音文件正確播放出來。效果圖:
暫停:
播放:
實現的效果:類似於音樂播放器一般,但是較之更簡單一些,可以正常播放語音,有拖動、快進后退效果便可。
思路:
首先想到的便是利用H5中的audio標簽來實現
<audio> 標簽定義聲音,比如音樂或其他音頻流。
可是最終卻發現原始的H5標簽播放的音頻效果,有點太牽強,其美觀程度遠遠達不到我們預期的,於是只能摒棄這樣的想法,另辟蹊徑了。最終想到最完美的解決方案依舊是利用H5的audio標簽,但是得重新定義它的滾動條以及前進、快退等事件。
參考資料:
HTML <audio>標簽 http://www.w3school.com.cn/tags/tag_audio.asp
HTML 5 視頻/音頻參考手冊 http://www.w3school.com.cn/tags/html_ref_audio_video_dom.asp
拜讀:https://segmentfault.com/a/1190000007332028
主要代碼:
<div class="container"> <div class="starter-template"> <h1>{{data.title}}</h1> <div class="vicoebox"> <div class="vicoebox-img"> <a href="javascript:void(0)" onclick="audioplay()" class="btn-play"></a> <img src="{{imgSiteUrl}}{{img}}" width="190" height="190"/> </div> <audio id="audio" preload type="audio/mpeg" src="{{imgSiteUrl}}{{data.content}}"></audio> <!-- 語音控制模塊開始 --> <div class="g-panel"> <div class="m-progress m-progress-song"> <div id="songprogress" class="progress"></div> <div id="songbar" class="progressbar"></div> <ul class="songtime"> <li class="start" id="start">0:00</li> <li class="end" id="end">0:00</li> </ul> </div> </div> </div> <!-- 語音控制模塊結束 --> </div> </div>
js:
<script type="text/javascript"> jQuery('.btn-play').click(function () { if (jQuery(this).hasClass("btn-play")) { audio.play(); jQuery(this).removeClass('btn-play').addClass('btn-pause'); } else { audio.pause(); jQuery(this).removeClass('btn-pause').addClass('btn-play'); } }); //---------------------------------工具方法開始 var Util = function () { // 格式化時間為分:秒的形式 function formatTime(seconds, curS) { var totalS = parseInt(seconds); var minute = Math.floor((totalS / 60)); var second = totalS - minute * 60; second = second < 10 ? ("0" + second) : second; return minute + ":" + second; } // 將時間轉化為百分比 function timeToPercent(curS, totalS) { var percent = parseInt((Number(curS) / Number(totalS)) * 100) + "%"; return percent; } // 更新時間 function updateTime(dom, seconds) { var result = formatTime(seconds); dom.html(result); } // 更新進度條 function updateProgress(dom, percent) { dom.css("width", percent); return true; } // 更新進度滑塊 function updateBarPos(dom, percent) { dom.css("left", percent); return true; } return { formatTime: formatTime, updateTime: updateTime, updateProgress: updateProgress, updateBarPos: updateBarPos, timeToPercent: timeToPercent, }; }(); //---------------------------------工具方法結束 //更新結束時間 jQuery("#audio")[0].addEventListener("loadedmetadata", function () { duration = this.duration;//獲取總時長 formatDuration = Util.formatTime(duration); jQuery('.end').html(formatDuration); }); function audioplay() { var audio = jQuery("#audio")[0]; var start = jQuery('.start');//開始時間 var end = jQuery('.end');//結束時間 var sprocontainer = jQuery(".m-progress-song");//歌曲進度條容器 var sProgress = jQuery("#songprogress"); var songbar = jQuery("#songbar");//歌曲進度條滑塊 // 監聽歌曲播放時間發生變化事件 audio.addEventListener("timeupdate", function () { var curS = audio.currentTime; var duration = audio.duration; var curPercent = Util.timeToPercent(curS, duration); // 更新歌曲時間,進度條 Util.updateTime(start, curS);//更新開始時間 Util.updateProgress(sProgress, curPercent); Util.updateBarPos(songbar, curPercent); }); //歌曲進度條滑塊滑動事件 songbar.on("touchstart", function (e) { e.preventDefault(); e.stopPropagation(); jQuery(audio).off("timeupdate"); audio.pause(); var totalW = jQuery(sprocontainer).width(); //播放條容器總長度 var leftDis = jQuery(sProgress).offset().left; var curS = 0; var curPercent = 0; var percent = ""; var touchMove = e.originalEvent.changedTouches[0].clientX; var dis = e.originalEvent.changedTouches[0].clientX - leftDis; songbar.on("touchmove", function (e) {//當觸點在觸控平面上移動時觸發touchmove事件 e.preventDefault(); e.stopPropagation(); touchMove = e.originalEvent.targetTouches[0].clientX; dis = touchMove - leftDis > totalW ? totalW : touchMove - leftDis; dis = touchMove - leftDis < 0 ? 0 : dis; percent = Math.floor(dis / totalW * 100) + "%"; Util.updateProgress(sProgress, percent); Util.updateBarPos(songbar, percent); }); songbar.on("touchend", function (e) {//當手指從屏幕上離開的時候觸發 e.preventDefault(); e.stopPropagation(); if (audio.paused) { audio.play(); jQuery('.btn-play').removeClass('btn-play').addClass('btn-pause'); } percent = Math.floor(dis / totalW * 100) + "%"; Util.updateProgress(sProgress, percent); Util.updateBarPos(songbar, percent); duration = audio.duration; curS = duration * parseInt(percent.replace("%", "")) / 100; audio.currentTime = curS; audio.ontimeupdate = function () { var curS = audio.currentTime; var curPercent = Util.timeToPercent(curS, duration); // 更新歌曲時間,進度條 Util.updateTime(start, curS); Util.updateProgress(sProgress, curPercent); Util.updateBarPos(songbar, curPercent); }; songbar.off("touchmove touchend"); }); }); // 歌曲進度條點擊事件 sprocontainer.on("mousedown", function (e) { var totalW = jQuery(sprocontainer).width(); var leftDis = jQuery(sProgress).offset().left; var curS = 0; var curPercent = 0; var dis = e.pageX - leftDis > totalW ? totalW : e.pageX - leftDis; percent = Math.floor(dis / totalW * 100) + "%"; sprocontainer.on("mouseup", function (e) { Util.updateProgress(sProgress, percent); Util.updateBarPos(songbar, percent); duration = audio.duration; curS = duration * parseInt(percent.replace("%", "")) / 100; audio.currentTime = curS; audio.ontimeupdate = function () { var curS = audio.currentTime; var curPercent = Util.timeToPercent(curS, duration); // 更新歌曲時間,進度條 Util.updateTime(start, curS); Util.updateProgress(sProgress, curPercent); Util.updateBarPos(songbar, curPercent); }; sprocontainer.off("mouseup"); }); }); // 歌曲播放完畢事件 audio.onended = function() { jQuery('.btn-pause').removeClass('btn-pause').addClass('btn-play'); }; } </script>
遇到的問題:
1.duration 獲取歌曲的總時間:H5中有獲取duration的方法,基本在音頻播放的事件里,此屬性起到了至關重要的作用;
2.移動端的觸摸事件:touchstart、touchend、touchmove:
touchstart事件:當手指觸摸屏幕時候觸發,即使已經有一個手指放在屏幕上也會觸發;
touchmove事件:當手指在屏幕上滑動的時候連續地觸發。在這個事件發生期間,調用preventDefault()事件可以阻止滾動;
touchend事件:當手指從屏幕上離開的時候觸發。
而每個Touch對象包含的屬性如下;
clientX:觸摸目標在視口中的x坐標;
clientY:觸摸目標在視口中的y坐標;
identifier:標識觸摸的唯一ID;
pageX:觸摸目標在頁面中的x坐標;
pageY:觸摸目標在頁面中的y坐標;
screenX:觸摸目標在屏幕中的x坐標;
screenY:觸摸目標在屏幕中的y坐標;
target:觸目的DOM節點目標。
關於這三個事件,其實挺有意思的:雖然自己之前很少接觸過移動端的開發,但是總是被身邊同事的各種“神技能”震撼到,而當自己真的將別人手中的“神技能”實現時,還是挺有成就感的,總感覺一切就是那樣神奇(哈哈……這也是為什么喜歡這份工作的原因,樂在其中。);
3.鼠標事件中的mousedown、mouseup(這兩種事件見得次數多了,也便不贅述了)。
滴答滴答前進中:
樂在其中,還需要永不止步。