Site icon Ryadel

Youtube Video in HTML modal lightbox popup

Youtube Video in HTML modal lightbox popup

If you've stumbled upon this post, it most likely means that you're looking for a way to insert a YouTube video within a HTML page in a modal/popup fashion.

Since I had to fullfill such task today, I would like to share the method I found, together with the open-source libraries I've used to implement that in a decent way, as well as a few hacks I made in order to have additional control over the various video events (play, pause, end, and so on) by using the YouTube APIs.

Are we ready? Let's start!

The Goal

My goal was quite simple: I had a standard HTML page with a Play button on it and I want to open a YouTube video (in autoplay mode) whenever my users clicked on it.

Here's the HTML page I'm talking about:

Youtube Video in HTML modal lightbox popup

And here's the behaviour I wanted to achieve when the user clicks on the Play button:

SPOILER: the above screenshot shows the end result, i.e. what we'll end up with at the end of the post. If you want to take a look at it live, visit www.thepaac.com and see it in action!

The Library

In order to achieve such result I've used Lity, a neat JS library that allows to embed a lot of iframe-based external contents (images, videos, maps, external URLs and so on) within a lightweight, accessible and responsive lightbox. In case you've never heard of it, a lightbox is basically a modal window that opens just like a popup over the HTML page, masking out the other content with a black (or white) background until you close it: that was precisely what I needed to achieve what I wanted!

The Lity JS library is available on GitHub (under MIT license), but you can also fetch it from its official website: however, I strongly suggest to get it from GitHub because the current "stable" version - which is the one you'll get by clicking the official website's Download button - has an odd bug that will prevent the Youtube APIs from working properly (see The Hack section below for further details on this).

Implementing Lity was a matter of minutes; I just had to perform the following steps:

  • Add a reference to the JS and CSS files from the Lity's /dist/ folder to the HTML page:
  • Put the Youtube URL in the <a> element that I was already using to render the Play button, and add a data-lity parameter on it:

... and that was it! The Lightbox showed up beautifully and everything was working just like I wanted.

The only thing I really didn't like in my solution was the fact that, at the end of the video, the Youtube player was showing the typical "other videos that you might like" dashboard, with a lot of other (mostly non-relevant) videos to click & see. In order to make things perfect I just needed to find a way to shut down that lightbox right after the video ends.

Unfortunately enough, this seemingly simple additional requirement took me a lot of time and efforts to implement. In the following sections I'll briefly explain how I was able to implement such feature, oping that this post will save other developers from losing that same amount of time.

The API

By looking at Lity source code and documentation, I immediately knew that such library couldn't help me to achieve my final goal: the whole Youtube playing feature was a "fire & forget" command, with no feedbacks provided by the HTML5 player.

However, there was a neat lity:ready event emitted by the library right after showing the lightbox on-screen that I could use for good: such event provided a instance variable containing the lity object with a close() method that could be used to shutdown the lightbox itself: I just needed to find a way to fire it at the end of the video. Or, in other words, I needed to receive a "notification" from the Youtube player of such kind that I could bind to a handler - a JavaScript function - that could close the lightbox.

In order to fullfill such requirement I started looking at the YouTube IFrame Player API, where I eventually managed to learn how to perform the following tasks:

  • Instantiate a Youtube Player JS object from an existing <iframe> element.
  • Bind that player's events to JavaScript methods (handlers).

Among those events there was one called onChangeState, which - according to the docs - gets activated every time the player state changes its status: Playing, Paused, Ended, and so on.

This was just what I needed to create my own JavaScript-based hack.

The Hack

Here's  the JS hack I've came up with in order to close the Lity's lightbox when the Youtube Video reaches its Ended status:

As we can see, the above code performs the following tasks:

  • Loads the YouTube IFrame Player API JS library.
  • Assign a JS event handler for the lity:ready event, which fires as soon as the lightbox has finished opening.
  • Retrieves the <iframe> HTML element created by Lity to host the Youtube video within its lightbox.
  • Assigns a ID to that iframe (required by the YouTube IFrame Player API to create the player object - see below).
  • Instantiates a JS player object by using the existing iframe.
  • Handles the onReady player event (to autoplay the video as soon as the player is ready) and the onStateChange event (to close the lightbox instance when the video ends).

NOTE: that same logic can be used for Vimeo videos as well: for further details on this, read this GitHub issue.

In order to make this hack work, the enablejsapi=1 parameter needs to be added to the Youtube embed URL in the following way:

For this very reason, we strongly suggest to use the 3.0.0-dev version of Lity (or greater), as v2.4.1 (the currently "stable" one that you will get by clicking to the Download button from the official non-GitHub website) has a weird QueryString handling feature that breaks the enablejsapi parameter while "forcing" the autoplay parameter, thus messing up everything. Luckily enough, v3.0.0-dev fixed such behavior.

Conclusion

That's basically it: I hope that this post will help other HTML and JS developers to embed Youtube videos in their website's HTML pages without losing too much time.

Happy coding!

 

Exit mobile version