I have a website that I have been working on that has a responsive background video. How it is supposed to work:
- Detect the screen size of the device (mobile screen vs. larger “desktop” screen)
- Preload the correct video on the blank htmtl background video element
- Quickly & gently fade the video element in once it loads
- Loop the video indefinitely, with no further fading or sharp transitions
- Monitor for screen size changes and reload a different video if necessary
document.addEventListener('DOMContentLoaded', function() {
var vid = document.querySelector('video'); // Adjust this selector to target your video element specifically.
var mobileReload = 0;
var initialLoad = 0;
function updateVideoSource() {
if (window.innerWidth <= 768 && mobileReload == 0) {
vid.classList.remove('is-loaded'); // Remove class before setting the correct source
mobileReload = 1;
vid.src = '/wp-content/uploads/2024/04/Homepage-Video-Mobile.webm'; // Add your mobile video path here.
vid.removeAttribute("loop");
vid.classList.add('is-loaded'); // Add class after setting the correct source
if (initialLoad == 0) {
initialLoad = 1;
vid.style.opacity = 0;
vid.oncanplaythrough = function() {
setTimeout(function() {
fade(vid);
}, 0.01);
};
}
}
if (window.innerWidth > 768) {
vid.classList.remove('is-loaded'); // Remove class before setting the correct source
mobileReload = 0;
vid.src = '/wp-content/uploads/2024/04/Homepage-Video-Desktop.webm'; // Add your default video path here.
vid.removeAttribute("loop");
vid.classList.add('is-loaded'); // Add class after setting the correct source
if (initialLoad == 0) {
initialLoad = 1;
vid.style.opacity = 0;
vid.oncanplaythrough = function() {
setTimeout(function() {
fade(vid);
}, 0.01);
};
}
} else {
// No update to avoid reloading when scrolling on mobile due to address bar resizing
}
}
function fade(element) {
var op = 0;
var timer = setInterval(function() {
if (op >= 1) clearInterval(timer);
element.style.opacity = op;
element.style.filter = 'alpha(opacity=' + op * 100 + ")";
op += op * 0.1 || 0.1;
}, 10);
}
// Add event listener for the 'ended' event to loop the video
vid.addEventListener('ended', function() {
vid.currentTime = 0; // Reset video to beginning
vid.play();
});
window.addEventListener('resize', updateVideoSource);
updateVideoSource(); // Call it on initial load as well.
});
The problem I am having is with Step 4. The loop works perfectly on the browser I use, develop, and test on (Firefox, and iOS Safari). But most consumers afaik use Chrome and there is an ugly gray fade stutter on Chrome when the video loops. Both videos are .WEBM and < 3mb. Any ideas?
As you can see I’m trying a couple of different things to fix it but neither are working.
I read that some browsers handle loops differently so I started by removing the loop attribute from the video. I know it would be easier to do that in the actual HTML but I’m kind of cheating and using a WP Cover Block as the video bg element and manipulating it with JS so this is just easier. Than I add an event listener to manually detect when the video ends and restart it. This doesn’t work.
I also added the variable initialLoad to prevent the fade event from running more than once, that isn’t working either, so I’m assuming it’s something to do with Chrome here.
Jordan P is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.