「JavaScript 30」學習筆記(十一)

前言

本文為「JavaScript 30」教學影片的學習筆記。

目標

學習對 HTML Video 進行操作。

筆記

首先取得所有的表單元素。

1
2
3
4
5
6
7
const player = document.querySelector('.player');
const video = player.querySelector('.viewer'); // 影片本身
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'); // 音量和速度

設定一個 togglePlay() 函式,以允許在滑鼠點擊影片時播放或暫停。

1
2
3
4
5
6
function togglePlay() {
const method = video.paused ? 'play' : 'pause';
video[method]();
}

video.addEventListener('click', togglePlay); // 滑鼠點擊時觸發
  • paused 屬性判斷影片是否暫停。

設定一個 updateButton() 函式,以切換播放按鈕。

1
2
3
4
5
6
7
function updateButton() {
const icon = this.paused ? '►' : '❚ ❚';
toggle.textContent = icon;
}

video.addEventListener('play', updateButton); // 影片播放時觸發
video.addEventListener('pause', updateButton); // 影片停止時觸發
  • toggle() 方法用來切換元素狀態。

設定一個 skip() 函式,以快轉或倒帶影片。

1
2
3
4
5
6
function skip() {
console.log(this.dataset);
video.currentTime += parseFloat(this.dataset.skip);
}

skipButtons.forEach(button => button.addEventListener('click', skip)); // 滑鼠點擊時觸發
  • dataset.skip 取得已經設定好的 data-skip 數値。

設定一個 handleRangeUpdate() 函式,以調整音量或播放速度。

1
2
3
4
5
6
function handleRangeUpdate() {
video[this.name] = this.value;
}

ranges.forEach(range => range.addEventListener('change', handleRangeUpdate)); // 事件物件改變時觸發
ranges.forEach(range => range.addEventListener('mousemove', handleRangeUpdate)); // 滑鼠移動時觸發
  • volume 屬性用來設置音量。
  • playbackRate 屬性用來設置播放速度。

設定一個 handleProgress() 函式,以允許用滑鼠點擊的方式更改影片播放位置。

1
2
3
4
5
6
function handleProgress() {
const percent = (video.currentTime / video.duration) * 100;
progressBar.style.flexBasis = `${percent}%`;
}

video.addEventListener('timeupdate', handleProgress); // 影片播放位置發生改變時觸發
  • duration 屬性代表影片長度。
  • flexBasis 屬性用來設置項目長度。

設定一個 scrub() 函式,以允許用滑鼠拖曳的方式更改影片播放位置。

1
2
3
4
5
6
7
8
9
10
11
function scrub(e) {
const scrubTime = (e.offsetX / progress.offsetWidth) * video.duration;
video.currentTime = scrubTime;
}

let mousedown = false; // 初始標記為 `false`
progress.addEventListener('mousedown', () => mousedown = true); // 按下滑鼠時標記為 `true`
progress.addEventListener('mousemove', (e) => mousedown && scrub(e)); // 滑鼠移動時且按下滑鼠時觸發
progress.addEventListener('mouseup', () => mousedown = false); // 鬆開滑鼠時標記為 `false`
progress.addEventListener('click', scrub); // 滑鼠點擊時觸發

  • e.offsetX 屬性代表事件物件在 X 軸上的偏移量。
  • offsetWidth 屬性代表元素的可見寬度。