今天要來做一個客製化的影片播放器
主要分為四個部分:
- 播放與暫停影片
- 音量與速度
- 快/倒轉
- 控制進度條
定義變數
1 | const myVideo = document.querySelector('video'); |
播放與暫停影片
點選播放按鈕與畫面時,需要播放或暫停
我們觸發對象為:1
2myVideo.addEventListener('click',playToggle)
playBtn.addEventListener('click',playToggle)
要做的事情為:1
2
3
4
5
6
7
8function playToggle(e){
playBtn.innerHTML = myVideo.paused ? '❚❚' : '►'
if(myVideo.paused){
myVideo.play()
}else{
myVideo.pause()
}
}
這裡還滿容易理解的,透過myVideo.paused
判斷狀態再決定播放或暫停。playBtn
用了三元運算子,判斷該顯示❚❚或►
音量與速度
一般的直覺可能會把音量和速度兩件事情拆開來做,但這邊巧妙的利用input的name來區分選取的對象,所以一開始定義的時候直接選取了所有的input
1
const inputBtn = document.querySelectorAll('input')
再透過forEach
分別去做事件的觸發1
2
3
4
5
6
7
8function setHandler(e){
const inputName = this.name//取得名稱volume或playbackRate
const inputValue = this.value//取得該input的值
myVideo[inputName] = inputValue
}
inputBtn.forEach((input)=>{
input.addEventListener('input',setHandler)
})
注意:用 點號
.
存取時,點號右邊必須是一個可識別字(identifier),例如屬性名稱,不能是字串、變數、運算式…等。但用 中括號[]
存取時,中括號裡面可以放字串、變數、運算式等。
來源1來源2
快/倒轉
這裡一樣透過一起選取button
再forEach分別做事件
再透過dataset
取得預設值,指定給currentTime
1
2
3
4
5
6function skipHandler(){
myVideo.currentTime += parseInt(this.dataset.skip) //轉化成數字 或直接*1
}
skipbtn.forEach((btn)=>{
btn.addEventListener('click',skipHandler)
})
進度條顯示
透過時間總長度(duration
)和現在時間(duration
)去算出百分比
timeupdate是一個事件,當currentTime更新時會觸發timeupdate事件。詳細介紹
1
2
3
4
5
6
7 processbar.style.flexBasis = 0 //可先歸零
myVideo.addEventListener('timeupdate',function(){
let allTime = this.duration
let progress = this.duration
percent = (progress/allTime)*100
processbar.style.flexBasis = percent +'%'
})
控制時間軸
這邊分為兩個部分,可以滑鼠按下或拖曳
拖曳必須是在mousedown的狀況下才能觸發,而且mouseup時必須關閉
觸發對象為整個時間軸1
const processbar_out = document.querySelector('.progress')
1 | processbar_out.addEventListener('mousedown', addListener); |
這裡我們透過mousedown
之後,重新再定義一次觸發條件,即符合我們要的mousedown後才能mousemove。
而在這邊我認為mouseup觸發的對象不是processbar_out
,使用者在拖曳時,有可能會離開我們原本的目標processbar_out
,導致關閉不了mousemove
,所以我將mosueup觸發對象設定為整個document
最後執行任務1
2
3
4
5
6
7function gotoTime(e){
let getPercent = (e.offsetX/this.offsetWidth)*100
//將百分比轉換回該影片實際時間位置
let currentTime = (getPercent*myVideo.duration)/100
processbar.style.flexBasis = getPercent +'%'
myVideo.currentTime = currentTime
}
- 取得滑鼠位置與
processbar_out
的寬算出百分比 - 因為我們要時間指定給
currentTime
所以要將百分比轉換回正確的時間值
補充
原始範例的做法是定義一個mousedown=false
的變數去判斷是否滑鼠按下來做觸發,
其中有一個很酷的寫法:1
progress.addEventListener('mousemove', (e) => mousedown && scrub(e));
這裡的&&
是而且的意思,在這藏了一個判斷式,也就是要執行scrub
的條件必須左右都為true,當mousedown = true,右邊的scrub
才會執行(也就是我們要的效果,mousedown才能mousemove)