Reputation: 63
I am trying to lazy load my html video. It's in my WordPress template and I want for video to load when user get to its viewpoint.
I am new in JS so I think something is wrong. How can I test if lazy loading is working correctly? Maybe my function is not valid?
<video id="myVideo" autoplay loop muted playsinline src="<?= VIDEO ?>/video_footer.mp4">
<source data-src="<?= VIDEO ?>/video_footer.mp4" type="video/mp4">
</video>
js:
$(function() {
$("video.myVideo source").each(function() {
var sourceFile = $(this).attr('data-src');
$(this).attr("src", sourceFile);
var video = this.parentElement;
video.load();
video.play();
});
});
Upvotes: 3
Views: 2984
Reputation: 811
It's unlikely that is working as it is.
You have already set the source
to video
so even if the function is working, the video file is already there, so no lazy load...
This is the correct setup:
<video id="myVideo" autoplay loop muted playsinline src="">
<source data-src="<?= VIDEO ?>/video_footer.mp4" type="video/mp4">
</video>
Then you can check if you function works
Another solution is to use intersection observer
and do it with pure JavaScript
, simple, lightweight and works in most cases
Lazy load video with pure JavaScript:
<script type="text/javascript">
const lazyvideo = document.querySelectorAll('.lazy-video');
observer = new IntersectionObserver(entries => {
entries.forEach(entry => {
if (entry.intersectionRatio > 0) {
console.log('video in the view');
if (entry.target.querySelector('source').getAttribute('data-src') !== null) {
const source = entry.target.querySelector('source').getAttribute('data-src')
entry.target.setAttribute('src', source);
}
observer.unobserve(entry.target);
} else {
console.log('video out of view');
}
});
});
lazyvideo.forEach(video => {
observer.observe(video);
});
</script>
I have added console.log('video out of view');
& console.log('video in the view');
in order to check the console whether the video is in view or not.
With this script if you want a video to be lazy loaded, just add a class lazy-video
to it and you are all set ;)
Full code:
const lazyvideo = document.querySelectorAll('.lazy-video');
observer = new IntersectionObserver(entries => {
entries.forEach(entry => {
if (entry.intersectionRatio > 0) {
console.log('video in the view');
if (entry.target.querySelector('source').getAttribute('data-src') !== null) {
const source = entry.target.querySelector('source').getAttribute('data-src')
entry.target.setAttribute('src', source);
}
observer.unobserve(entry.target);
} else {
console.log('video out of view');
}
});
});
lazyvideo.forEach(video => {
observer.observe(video);
});
#myVideo {
max-width:400px;
width:100%;
}
<video id="myVideo" class="lazy-video" autoplay loop muted playsinline src="">
<source data-src="http://commondatastorage.googleapis.com/gtv-videos-bucket/sample/BigBuckBunny.mp4" type="video/mp4">
</video>
If you want to be sure that lazy load works
Network
and select the
media
tabSee screenshots below:
Not there yet:
In view:
Upvotes: 3