Identifying the primary issue:
The issue lies in your input
being wrapped inside a span
, causing the event to bubble up to the parent SPAN and triggering mute on input click.
Enhanced handling of custom video events:
While utilizing the older fa
icons, you have the freedom to adjust the CSS according to the latest fas
specifications.
The JavaScript example provided is quite straightforward, but don't hesitate to seek guidance if needed!
Take note of the newly introduced .is-muted
and .is-paused
CSS classes!
These classes are essential for the trick, in conjunction with the JS's classList.toggle()
Follow these guidelines:
- The custom UI elements should purely manipulate the
video
Element properties.
- The appearance and styles of custom UI elements should be solely controlled by the events triggered by the
video
element:
const video = document.getElementById('video');
const playBtn = document.getElementById('playBtn');
const muteBtn = document.getElementById('muteBtn');
const volBar = document.getElementById('volBar');
// CUSTOM UI ELEMENTS EVENTS
// They should only change the `video` properties!
// REMEMBER: we don't handle the UI appearance here
playBtn.addEventListener('click', () => {
video[video.paused?'play':'pause']();
});
muteBtn.addEventListener('click', () => {
if (!video.volume) return; // Do nothing if there's no volume whatsoever
video.muted = !video.muted; // Toggle muted state
});
volBar.addEventListener('input', (evt) => {
video.volume = evt.target.value;
});
// VIDEO EVENTS - AND UI STYLES
// Triggered on video property value change
// https://developer.mozilla.org/en-US/docs/Web/Guide/Events/Media_events
video.addEventListener('play', handlePlayPauseUI );
video.addEventListener('ended', handlePlayPauseUI );
video.addEventListener('pause', handlePlayPauseUI );
video.addEventListener('volumechange', handleVolumeUI );
// TODO: Handle also 'progress', 'ratechange', etc...
function handlePlayPauseUI () {
playBtn.classList.toggle('is-playing', !video.paused);
}
function handleVolumeUI() {
volBar.value = video.muted ? 0 : video.volume;
muteBtn.classList.toggle('is-muted', video.muted || !video.volume);
}
video {display: block; max-width: 500px;}
.fa {
user-select: none;
cursor: pointer;
}
.fa.is-muted:before{ /* I used .fa, you use .fas */
font-family: "FontAwesome"; /* Fix also the family name if needed */
content: "\f026"; /* HEX for the "mute" icon (find yours in the cheatsheet CSS docs)*/
}
.fa.is-playing:before {
font-family: "FontAwesome";
content:"\f04c"; /* set here the HEX for pause icon */
}
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css">
<video id="video" autobuffer controls>
<source src="http://clips.vorwaerts-gmbh.de/big_buck_bunny.ogv" type="video/ogg">
<source src="http://clips.vorwaerts-gmbh.de/big_buck_bunny.mp4" type="video/mp4">
<source src="http://clips.vorwaerts-gmbh.de/big_buck_bunny.webm" type="video/webm">
</video>
<span id="playBtn" class="fa fa-fw fa-play"></span>
<span id="muteBtn" class="fa fa-fw fa-volume-up"></span>
<input id="volBar" type="range" value="1" min="0" max="1" volume="1" step="0.1">
By adopting the approach outlined above, it eliminates the distinction whether you interact with the default UI handlers of the video
or your custom UI handlers.
With this knowledge in hand, you can proceed to add the missing functions for 'progress', 'ratechange', and other VideoElement Events, and subsequently remove the controls
property from the HTML video
element.