Using this code to autoplay a series of videos, depending on if they are in the viewport:
/**AUTOPLAY VIDEO IN VIEWPORT**/
function playPauseVideo() {
let videos = document.querySelectorAll("video");
videos.forEach((video) => {
// We can only control playback without insteraction if video is mute
video.muted = true;
// Play is a promise so we need to check we have it
let playPromise = video.play();
if (playPromise !== undefined) {
playPromise.then((_) => {
let observer = new IntersectionObserver(
(entries) => {
entries.forEach((entry) => {
if (
entry.intersectionRatio !== 1 &&
!video.paused
) {
video.pause();
} else if (video.paused) {
/*setTimeout(function() {
video.play();
}, 5000);*/
video.play();
}
});
},
{ threshold: 1}
);
observer.observe(video);
});
}
});
}
// And you would kick this off where appropriate with:
playPauseVideo();
I'm trying to understand why, when I scroll the video into view it plays as expected, but if the video is finished and I begin to scroll further the video will start again even if it is only partly in the viewport. I want the video(s) to stay paused/stopped until it is completely back into the viewport. The threshold for IntersectionObserver is set to 1 - so this behaviour is confusing me. Any ideas?
You are making it too complicated. you don't need to check audio.play()
as it will play the videos unnecessarily.
here is how I would code it:
function handleIntersection(entries) {
entries.forEach(entry => {
const video = entry.target;
if (entry.isIntersecting) {
video.play();
} else {
video.pause();
}
});
}
const observer = new IntersectionObserver(handleIntersection, {
threshold: 1.0
});
const videos = document.querySelectorAll('.video');
videos.forEach(video => {
observer.observe(video);
});