So for reasons we will ignore, you have a bunch of videos on your site that autoplay. Given the data these videos gobble up, maybe it would be good to automatically pause the videos when they aren't on screen?

This little code snippet will do just that. It finds all the videos on the page and then uses an Intersection Observer to play them when they are in view, then pause them when they go out of view.

You can also tweak the threshold so that the videos start to play, say when just a little of them enters the viewport, or the entire video is visible – and everything inbetween.

Minimal example

I cut a video from the wonderful NASA archive into clips with some dummy text. Scroll this page up/down and you should be able to see the videos start/stop: https://benfrain.com/playground/video-stop-start/index.html

The code

Anyway, you came for the code! Here it is:

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) {
                                video.play();
                            }
                        });
                    },
                    { threshold: 0.2 }
                );
                observer.observe(video);
            });
        }
    });
}

// And you would kick this off where appropriate with:
playPauseVideo();

What it does

We grab all your videos, make sure they are muted, as you can't control autoplay/pause videos with audio, and if the video is there (as in it is playable) we set up an observer to watch the video in the DOM, if it is in view, we play, if it leaves the view we pause.

Tweaking the threshold

The only thing you may want to toggle is the threshold which sits inside the options object. 1 means the video has to be fully visible before it will play, something like 0.1 would only need a sliver of it visible to start playing.