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 for about half a second 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- as in, it works exactly the same as having the loop attribute in the html and doesn’t fix the issue.
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.