Creating a simple Youtube Lightbox
By combining everything we've learned in the last 2 sections- making our Youtube iframe responsive and centered, plus loading and manipulating it through the Youtube Player API- we're ready to create a simple lightbox that pops up to show our desired Youtube video when launched.
Demo: Click on one of the sample links below to launch a Youtube video inside lightbox: Video 1 | Video 2 | Video 3
You can also view the demo on a separate page.
Lets go through how the script is created now, step by step.
The lightbox Interface
To create the lightbox interface, we'll use the same technique and setup discussed in the first section to display an iframe that's both responsive and centered in the middle of the page:
<head> <link rel="stylesheet" href="youtubelightbox.css" /> </head> <body> <!-- Add this to bottom of page --> <div id="youtubelightbox" class="parent"> <div class="centeredchild"> <div class="videowrapper"> <div id="playerdiv"></div> </div> </div> </div> </body>
If you look inside
youtubelightbox.css, everything should look familiar to you
based on what you've read in the previous section. We hide the
interface initially
by setting the top level container to "display: none
".
Also, notice that instead of actually embedding a youtube iframe in
the heart of the lightbox, we insert a temporary DIV '<div
id="player"></div>
'. This DIV will be dynamically replaced
with a Youtube iframe using the Youtube Player API later.
Defining the links that will trigger the lightbox
Before getting to our actual lightbox script, we also need to
decide how it should be triggered. A simple yet versatile set up is
to attach the lightbox to any link on the page that points to a
Youtube video and carries a CSS class of "lightbox
"- whenever the
user clicks on one of those links, we want the lightbox to be shown
and the Youtube video played. Here are some example links
that we want the lightbox to be triggered for when clicked on:
<p> Click on one of the sample links below to launch a Youtube video inside lightbox: <a href="https://www.youtube.com/watch?v=Pe0jFDPHkzo" class="lightbox">Video 1</a> | <a href="https://youtu.be/oIlIVFBBbNw" class="lightbox">Video 2</a> | <a href="https://www.youtube.com/watch?v=fzrfrXhE-w4" class="lightbox">Video 3</a> </p>
We'll design the script to recognize a Youtube link by way of its
"lightbox
" class name, and then to extract the Youtube
video ID portion of the link to feed into Youtube Player API the
video to play. Youtube links come in a variety of forms, and we'll
use a robust regular expression to get to the video ID portion of
the link regardless.
Creating the lightbox script
We've defined the interface for the lightbox and how it should be activated- only thing left to do is to create the script! We'll use plain JavaScript here (no jQuery). Here it is, followed by an explanation:
<!-- Add this to bottom of page after the lightbox markup--> <script> // load Youtube API code asynchronously var tag = document.createElement('script') tag.src = "https://www.youtube.com/iframe_api"; var firstScriptTag = document.getElementsByTagName('script')[0] firstScriptTag.parentNode.insertBefore(tag, firstScriptTag) var isiOS = navigator.userAgent.match(/(iPad)|(iPhone)|(iPod)/i) != null //boolean check for iOS devices var youtubelightbox = document.getElementById('youtubelightbox') var player // variable to hold new YT.Player() instance // Hide lightbox when clicked on youtubelightbox.addEventListener('click', function(){ this.style.display = 'none' player.stopVideo() }, false) // Exclude youtube iframe from above action youtubelightbox.querySelector('.centeredchild').addEventListener('click', function(e){ e.stopPropagation() }, false) // define onYouTubeIframeAPIReady() function and initialize lightbox when API is ready function onYouTubeIframeAPIReady() { createlightbox() } // Extracts the Youtube video ID from a well formed Youtube URL function getyoutubeid(link){ // Assumed Youtube URL formats // https://www.youtube.com/watch?v=Pe0jFDPHkzo // https://youtu.be/Pe0jFDPHkzo // https://www.youtube.com/v/Pe0jFDPHkzo // and more //See http://stackoverflow.com/a/6904504/4360074 var youtubeidreg = /(?:youtube\.com\/(?:[^\/]+\/.+\/|(?:v|e(?:mbed)?)\/|.*[?&]v=)|youtu\.be\/)([^"&?\/ ]{11})/i; return youtubeidreg.exec(link)[1] // return Youtube video ID portion of link } // Creates a new YT.Player() instance function createyoutubeplayer(videourl){ player = new YT.Player('playerdiv', { videoId: videourl, playerVars: {autoplay:1} }) } // Main Youtube lightbox function function createlightbox(){ var targetlinks = document.querySelectorAll('.lightbox') for (var i=0; i<targetlinks.length; i++){ var link = targetlinks[i] link._videoid = getyoutubeid(link) // store youtube video ID portion of link inside _videoid property targetlinks[i].addEventListener('click', function(e){ youtubelightbox.style.display = 'block' if (typeof player == 'undefined'){ // if video player hasn't been created yet createyoutubeplayer(this._videoid) } else{ if (isiOS){ // iOS devices can only use the "cue" related methods player.cueVideoById(this._videoid) } else{ player.loadVideoById(this._videoid) } } e.preventDefault() }, false) } } </script>
After loading the Youtube Player API asynchronously, the first thing
we do is assign "click" behaviour to the main "#youtubelightbox
"
container, so clicking on it dismisses the lightbox and stops
playing the video. However, we want users to be able to interact
with the Youtube iframe inside it without it disappearing, so we make an
exception for clicks occurring inside the iframe container (".centeredchild
").
Moving on, we define the onYouTubeIframeAPIReady()
that Youtube
API automatically calls when the API is loaded, and instead of
initializing a Youtube player at this point, we simply initialize
the Lightbox. We'll wait until the user actually clicks on a Youtube
link before initializing the Youtube player:
function onYouTubeIframeAPIReady() { createlightbox() }
Following the above, function getyoutubeid(link)
gets the ID
portion of a Youtube link to feed into Youtube API to play a
specific video. The regular expressions used is
discussed here. Function createyoutubeplayer(videourl)
takes a Youtube video ID and creates a Youtube player using it, by
creating an instance of new YT.Player()
. We'll only be
creating the Youtube player once, the first time the user clicks on
a Youtube link. Subsequent clicks will simply cause the existing
player to play the desired video.
Last but not least, we arrive at function createlightbox()
,
which ties everything together. Firstly, it gathers up all links on
the page with class ".lightbox", then iterates through each of them
to assign a "click" event handler to them. When the user clicks on
these links, the script displays the lightbox interface while either
creating a Youtube player or simply plays the target video depending
on whether the player is already present.
As mentioned in the previous section on Mobile Devices Playback, in iOS devices such as iPhone and iPad, Youtube API's "play" related functions not only do not play the requested video, but puts the player in "perpetual" buffering mode, essentially disabling the player altogether. To overcome this nasty bug, inside our lightbox script, we detect iOS devices, and when a link is clicked on, simply "cue" the corresponding video instead of play it in those devices:
if (isiOS){ // iOS devices can only use the "cue" related methods player.cueVideoById(this._videoid) } else{ player.loadVideoById(this._videoid) }
This loads up the video in the lightbox for iOS users but doesn't attempt to play it (and triggering the bug), leaving it up to the user to click "play".
- Tutorial introduction- using CSS to make a Youtube iframe responsive and vertically centered
- Controlling a Youtube video via URL parameters and the Youtube Player API
- Creating a simple Youtube lightbox
End of tutorial