DEV Community

Cover image for Case: JS Intersection Observer usage within iFrame
Ilya Gorenburg
Ilya Gorenburg

Posted on

Case: JS Intersection Observer usage within iFrame

Wanted to share our experience using Intersection Observer API.

In short, what is Intersection Observer API:

...provides a way to asynchronously observe changes in the intersection of a target element with an ancestor element or with a top-level document's viewport. It fires a JavaScript event if the element on a page becomes visible/invisible in the user's viewport. It relies on the native browser's API.

In our project we allowed users to upload GIF images to showcase their works. At the time of launching the project, it suited great everyone - users (they knew how to deal with GIF images) and developers (no need to convert videos from various formats to H.265). One day we decided to add support of the video clips with the same functionality as GIF images: autoplay, looped, no audio. Users liked the new feature - no doubt, the video's 4K quality can't be compared with 256-color GIF. And it started a disaster on the client-side - users started uploading 10 videos per project and they all started running in the loop when the user was opening the project's page.

Page view with all videos visible

We needed to take an action. We decided to add Intersection Observer in the game.

Each video that the user embeds is being inserted on the page via iframe. And each iframe can have its own intersection observer that will fire when the iframe becomes visible/invisible on the screen. So instead of initializing the intersection object on the parent page, we initialize it within the iframe.

Page view within user's viewport visibility

And it works great. Once the video is on the screen - the video automatically starts playing. Once the video becomes invisible on the page - we put it on pause.

Initializing intersection observer is easy:

const videoBlockEl = document.getElementById('video')
const videoPlayerEl = document.getElementById('video-player')
let isVideoVisible = false
const videoObserverOptions = { threshold: .05 }

const videoObserver = new IntersectionObserver(event => {
  isVideoVisible = event[0].isIntersecting

  if (!isVideoVisible) {
    videoPlayerEl.pause()
  }
  if (isVideoVisible) {
    videoPlayerEl.play()
  }

}, videoObserverOptions)

videoObserver.observe(videoBlockEl)
Enter fullscreen mode Exit fullscreen mode

If you use observers in single-page applications, don't forget to disconnect from observer when you no longer need them:

videoObserver.disconnect()

Benefits of this approach:

  • Ship the code easily - you don't have to support any of the code on the parent page
  • Intersection Observer API is available and working even if the iframe is being embedded anywhere else
  • Dependency free code with just a few lines of vanilla javascript

Top comments (3)

Collapse
 
haniamalik2 profile image
HaniaMalik2 • Edited

Thanks for sharing I must share with the my friend too... Really Appreciated..... URL

Collapse
 
ivanbozhkov profile image
Ivan Bozhkov

I'm failing to find the differences you experienced while using intersection observer with an iframe.

Collapse
 
gorenburg profile image
Ilya Gorenburg

Let's say you have 10 videos on the page embedded via iframe. They all autoplay (just like a GIF image). The performance of the page would be terrible (playing 10 videos simultaneously), especially on mobile device. Intersection observer which is being used in each iframe tracks if the iframe is visible to the user at this moment or now. If it's not visible - it will pause the video. Once the iframe would become visible - it will start autoplay. This way you would have an experience of 10 videos with autoplay, but only those which are visible would be actually playing - the rest would be on pause