Lazy loading videos

I’ve seen several sites containing scripts to handle lazy loading of images (meaning, it displays images only when the user scrolls to their location further down the page).

Is there any such script for lazy loading YouTube videos that are displayed in iframes?

At the very least, what is involved in detecting where the user is scrolled to?

There’s this.
LazyYT.js: A jQuery plugin to lazy load Youtube videos
Never used it though.

It is good enough that Discourses uses it too (at least as a plugin, which is included by default) :slight_smile:

Thank you for the idea. Unfortunately, my pages are not using Jquery (not needed on ay of the pages) and I hesitate to include it in this mobile version.

Sitepoint recently had an article on Yourtube videos and using JavaScript and Json to eliminate iFrames and download an image along with relevant information. I am in the process of fine tuning this process for my needs and the latest version can be seen here:

http://www.johns-jokes.com/videos

I am curious to know if this technique will satisfy your mobile version? If so I will supply source code that currently:

  1. calls a single PHP function with a YoutubeID
  2. uses JSON to extract all Youtube video information
  3. downloads background image, title, blurb, etc in a formatted string
  4. can use your own title and blurb info’
  5. is very fast or just quicker?
  6. W3.org validation of HTML & CSS without errors
  7. does not use frames
  8. best thing since sliced bread?

The site is not currently using PHP, sorry. Hope to later when all is settled.

Yeah, you are quite correct.
The plugin is small and only makes use of a handful of jQuery methods, so I rewrote it to plain JS.
You can get it here.

I’ll post the code, too, in case it helps anyone else.

'use strict';

var LazyYT = (function () {
  function setUp(el) {
    var width = el.dataset.width,
        height = el.dataset.height,
        ratio = el.dataset.ratio,
        id = el.dataset.youtubeId,
        aspectRatio = ['16', '9'],
        paddingTop = 0,
        youtubeParameters = el.dataset.parameters || '';

    if (typeof width === 'undefined' || typeof height === 'undefined') {
      height = 0;
      width = '100%';
      aspectRatio = (ratio.split(':')[1] / ratio.split(':')[0]) * 100;
      paddingTop = aspectRatio + '%';
    } else {
      height = height + 'px';
      width = width + 'px';
    }

    el.style.position = 'relative';
    el.style.height = height;
    el.style.width = width;
    el.style.paddingTop = paddingTop;
    el.style.background = 'url(http://img.youtube.com/vi/' + id + '/hqdefault.jpg) center center no-repeat';
    el.style.cursor = 'pointer';
    el.style.backgroundSize = 'cover';

    el.innerHTML = '<p id="lazyYT-title-' + id + '" class="lazyYT-title"></p><div class="lazyYT-button"></div>';
    el.classList.add('lazyYT-image-loaded');

    var request = new XMLHttpRequest();
    request.open('GET', 'https://gdata.youtube.com/feeds/api/videos/' + id + '?v=2&alt=json', true);
    request.onload = function() {
      if (request.status >= 200 && request.status < 400){
        var data = JSON.parse(request.responseText);
        document.getElementById('lazyYT-title-' + id).innerHTML = data.entry.title.$t;
      }
    };
    request.send();

    el.addEventListener('click', function(e) {
      e.preventDefault();
      if (!el.classList.contains('lazyYT-video-loaded') && el.classList.contains('lazyYT-image-loaded')) {
        el.innerHTML = '<iframe width="' + width + '" height="' + height + '" src="http://www.youtube.com/embed/' + id + '?autoplay=1&' + youtubeParameters +  '" style="position:absolute; top:0; left:0; width:100%; height:100%;" frameborder="0" allowfullscreen></iframe>';
        el.classList.remove('lazyYT-image-loaded');
        el.classList.add('lazyYT-video-loaded');
      }
    }, false);
  }

  return {
    init: function(selector) {
      var els = document.querySelectorAll(selector);
      [].forEach.call(els, function(el) {
        el.style.cursor = 'pointer';
        setUp(el);
      });
    }
  };
})();

You include the script in your page and initialize with: LazyYT.init(".js-lazyYT");

You might run into a couple of issues with older browsers, but at least this should let you test things.
If you did use it, we could always make the code more robust.

HTH

So what this script does is load only a preview of the video so it loads faster? The iFrame version doesn’t do that already? Thanks for any clarification!

When I use an iFrame, then clicking on the still image plays the video in every case.

This is almost true with LazyYT: In one case, the image would not play, saying that it must be played on YouTube. It was disabled for playback on other websites by the video owner. Yet it played fine in the embedded iFrame code.

Thought you would like to know!

The script loads a preview image, then waits until the video is actually clicked to load and start the full Youtube video.
If you embed an iframe then when a user hits your page, then they will download whatever is contained in the iframe.

Oh ok. That sounds a bit strange, but I would need to take a closer look.

I was wrong. The video is not playable outside YouTube, period. It’s not your script that’s wrong, but owner permissions.