This is a JavaScript practice with JavaScript30 by Wes Bos without any frameworks, no compilers, no boilerplate, and no libraries.
view demo here
video.paused
, video.currentTime
, dataset
of .data-
attribute, parseFloat()
user .querySelector
or .querySelectorAll
to get the elements we need to build up the panel for video player
const player = document.querySelector('.player');
const video = document.querySelector('.viewer');
const progress = document.querySelector('.progress');
const progressBar = document.querySelector('.progress__filled');
const toggle = document.querySelector('.toggle');
const skipButtons = document.querySelectorAll('[data-skip]');
const ranges = document.querySelectorAll('.player__slider');
-
function togglePlay()
- click the video to play
.paused
is the property ofvideo
and there is no
.playing
property live onvideo
function togglePlay() { const method = video.paused ? 'play' : 'pause'; video[method](); }
above code equals to:
video[vdeo.paused ? 'play' : 'pause']();
and
if(video.paused) { video.play(); } else { video.pause(); }
-
function updateButton()
- toggle the play button during the video plays or pauses
to change icon, in this case is change the
textContent
propertyconst icon = this.paused ? '►' : '❚ ❚'; // `this` is the `video` toggle.textContent = icon; console.log({toggle}); // log the `{toggle}` out to see where the `textContent` is
-
function skip()
- click the skip buttons to skip
the two skip buttons are:
<button data-skip="-10"></button>
and<button data-skip="25"></button>
console.log(this.dataset.skip); video.currentTime += parseFloat(this.dataset.skip);
console.log(this.dataset)
can get the information which is the value we just added asdata-skip
attribute on HTML like:then we use its
skip
property andparseFloat
into a float number to-10s
or+25s
thecurrentTime
-
function handleRangeUpdate()
- handle the two input sliders
the two input sliders are:
<input type="range" name="volume">
and<input type="range" name="playbackRate">
console.log(`${this.name}: ${this.value}`); video[this.name] = this.value;
the
name
ofthis.name
is thevolume
orplaybackRate
, just what we define thename
attributes of the inputs on HTML -
function handleProgress()
- update the progress bar when the video plays
percent
defines the width ofprogressBa
r'sflexBasis
const percent = (video.currentTime / video.duration) * 100; progressBar.style.flexBasis = `${percent}%`; console.log(percent);
-
function scrub(e)
- change the progress bar width when drag or click on it
to
console.log(e)
theMouseEvent
out and you will find theoffsetX
which is relative to the progressoffsetWidth
, use them to calculate thescrubTime
and then update the video'scurrentTime
const scrubTime = (e.offsetX / progress.offsetWidth) * video.duration; video.currentTime = scrubTime; console.log(e);
-
click the video to play
video.addEventListener('click', togglePlay);
-
toggle the play button icon when the video plays or pauses
video.addEventListener('play', updateButton); video.addEventListener('pause', updateButton);
-
update the progress bar when the video plays
video.addEventListener('timeupdate', handleProgress);
-
toggle the play butotn to play or pause
toggle.addEventListener('click', togglePlay);
-
click to skip (to
-10s
or+25s
)skipButtons.forEach(button => button.addEventListener('click', skip));
-
handle range input sliders
add
mousemove
event for updating real-time, rather than just when we let go of the buttonranges.forEach(range => range.addEventListener('change', handleRangeUpdate)); ranges.forEach(range => range.addEventListener('mousemove', handleRangeUpdate));
-
change the progress bar width when we click or drag on it
progress.addEventListener('click', scrub);