iT邦幫忙

2024 iThome 鐵人賽

DAY 11
0
JavaScript

火箭通關JS30系列 第 11

JS30-11-Custom Video Player

  • 分享至 

  • xImage
  •  

課程目的:

這次的內容是如何自訂視訊播放器,雖然現在HTML的**:視訊嵌入要素**的功能對想要在網站上撥放影片已經綽綽有餘了,不過能夠學習到如何自己手刻功能也是一個寶貴的經驗。
作品實做

本次功能實作重點:

  • 點擊video撥放影片以及暫停
  • 暫停以及播放時的播放鍵轉換"►" : "❚ ❚”
  • 設定快轉25s及後退10s的功能
  • 聲音大小及播放速度
  • 隨著時間更新進度條
  • 點擊進度條跳轉時間

這裡是綁訂的各項元素

const player = document.querySelector(".player");
const video = player.querySelector(".viewer"); //video視訊嵌入要素
const progress = player.querySelector(".progress"); //總共時間的進度條
const progressBar = player.querySelector(".progress__filled");//當下時間進度條
const toggle = player.querySelector(".toggle"); //播放鍵
const skipButtons = player.querySelectorAll("[data-skip]"); //快轉倒退鍵
const ranges = player.querySelectorAll(".player__slider"); //音量及影片速度滑動條

點擊video撥放影片以及暫停

function togglePlay() {
  const method = video.paused ? "play" : "pause"; 
  video[method](); 
}

video.addEventListener("click", togglePlay); 
toggle.addEventListener("click", togglePlay);
  1. 設定變數method,內容為一個字串,作為video方法的名稱
  2. 如果video.paused屬性為true(偵測影片為停止狀態則播放影片),method = "play"
  3. video[method](),JavaScript 會首先查找 method 變數所指向的字串,然後調用該字串所代表的 video 物件的方法。假設method=”play”,則等同於video.play()
  4. videotoggle監聽到”click”時,調用togglePlay,即當我們點擊了畫面或者播放鍵來控制影片暫停或播放

暫停以及播放時的播放鍵轉換"►" : "❚ ❚”

function toggleButton() {
  const icon = this.paused ? "►" : "❚ ❚";
  toggle.textContent = icon;
  toggle.classList.add("icon-change");
  setTimeout(() => {
    toggle.classList.remove("icon-change");
  }, 300); 
}
video.addEventListener("play", toggleButton);
video.addEventListener("pause", toggleButton);
  1. 設定變數icon,如果video為暫停狀態輸出字串 "►" 否則"❚ ❚"
  2. toggle.textContent =icon,如果icon 是"►”,將 textContent改為 "►”
  3. 在video監聽到"play""pause"時,調用toggleButton,即在暫停或播放時將icon改成對應的字串

設定快轉25s及後退10s的功能

function skip() {
  video.currentTime += parseFloat(this.dataset.skip);
}

skipButtons.forEach((buttons) => buttons.addEventListener("click", skip));

因為skipButtons為[data-skip]類的按鈕元素的** NodeList**,所以我們必需為每個按鈕添加一個事件監聽器,而forEach是一個非常方便的方法

流程為:

抓取每一個按鈕⇒為每個按鈕添加監聽器⇒觀察哪個按鈕被點擊⇒調用skip函式

this.dataset.skip:dataset為我們自己在html設定的data-* attribute(自訂 data 屬性),分別設置的數值為data-skip="-10”、data-skip="25”,而我們取的是data-skip內的value

當我們監聽到click事件時,運行video.currentTime += parseFloat(this.dataset.skip),即video的當前時間+當前點擊的按鈕的data-skip的值

聲音大小及播放速度

function handleRangeUpdate() {
  video[this.name] = this.value;
}

ranges.forEach((slider) => {
  slider.addEventListener("change", handleRangeUpdate);
});
ranges.forEach((slider) => {
  slider.addEventListener("mousemove", handleRangeUpdate);
});

我們分別設置的input的name為volume、playbackRate還有value的預設值

this.value 代表了當前滑桿(或其他控件)的值,這是用來動態調整 video 元素的某些屬性(例如音量、播放速度等)

在監聽到"change"(改變)以及"mousemove(滑鼠移動)之後調動函式

隨著時間更新進度條

function handleProgress() {
  const percent = (video.currentTime / video.duration) * 100;
  progressBar.style.flexBasis = `${percent}%`;}
  
  video.addEventListener("timeupdate", handleProgress); *//隨著時間更新進度條*

設定變數percent算出當前時間/總時長的百分比

更改**flexBasis的%**數達到自動伸展的效果

video.addEventListener("timeupdate")為監聽到影片時間更新並調動函式

點擊進度條跳轉時間

function scrub(e) {
  const scrubTime = (e.offsetX / progress.offsetWidth) * video.duration;
  video.currentTime = scrubTime;
}

let mousedown = false;
progress.addEventListener("click", scrub); //點選進度條更新
progress.addEventListener("mousemove", (e) => mousedown && scrub(e));
progress.addEventListener("mousedown", () => (mousedown = true));
progress.addEventListener("mouseup", () => (mousedown = false));

scrubTime = (e.offsetX / progress.offsetWidth) * video.duration;
這是在計算當進度條在offsetX位置時,在progress總寬的比例對應的影片時間
mousedown變數用來確保只有在按住鼠標並拖動時,mousemove 事件才會更新影片時間。這避免了在不按住鼠標時移動鼠標導致影片自動拖動。
mousedown && scrub(e)為如果mousedown 為真,則調動 scrub(e)

最後重點整理 :

 const method = video.paused ? "play" : "pause"; 
  video[method](); 
  • 使用三元判斷式可以做到code更為簡潔
  • videomethod等同於video.method()這種方法呼叫方式的好處是,它可以在運行時期動態地決定要調用的方法
(e) => mousedown && scrub(e)

這段扣是運用短路求值的語法,如果左邊的操作數 (mousedown) 為 true,那麼它會繼續執行右邊的操作 (scrub(e))。 如果左邊的操作數為 false,那麼整個表達式立即返回 false,右邊的操作就不會執行。

導讀文件以及學習資源

[ Alex 宅幹嘛 ] 👨‍💻 深入淺出 Javascript30 快速導覽 | Day 11:Custom Video Player
JS30


上一篇
JS30-10 - Hold Shift and Check Checkboxes
下一篇
JS30-12 - Key Sequence Detection
系列文
火箭通關JS3030
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言