Skip to content

Instantly share code, notes, and snippets.

@kevinweber
Last active June 29, 2016 04:52
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save kevinweber/6216fa27f616cc4a38ce06a634d89850 to your computer and use it in GitHub Desktop.
Save kevinweber/6216fa27f616cc4a38ce06a634d89850 to your computer and use it in GitHub Desktop.
/*global jQuery */
/**
* $.responsiveVideo
* by Kevin Weber
*
* Improve responsiveness of videos.
* Libraries required: jQuery.
*
* Initiate plugin like this:
* var options = {
* dataSrc: 'custom-data-src'
* ...
* }
*
* $('video').responsiveVideo(options);
*/
(function ($) {
'use strict';
var pluginName = "responsiveVideo",
pluginObject = this,
// These settings can be overridden when initializing this plugin
settings = {
dataSrc: 'data-src'
};
/*
* The actual plugin constructor
*/
function Plugin(element, options) {
pluginObject = this;
/**
* The element the plugin was initiated on
* @type {jQuery}
*/
pluginObject.$wrapper = $(element);
// Extend default settings
$.extend(settings, options);
// Initiate the plugin
pluginObject.init();
}
/**
* Debounce function
* from https://gist.github.com/kevinweber/86532b4a7f01212b65e60b3faf051550
*/
function debounce(func, wait, immediate) {
var timeout;
return function () {
var context = this,
args = arguments,
later,
callNow;
later = function () {
timeout = null;
if (!immediate) {
func.apply(context, args);
}
};
callNow = immediate && !timeout;
clearTimeout(timeout);
timeout = setTimeout(later, wait);
if (callNow) {
func.apply(context, args);
}
};
}
function hasVisibilityChanged() {
return pluginObject.$wrapper.wasVisible !== pluginObject.$wrapper.isVisible;
}
/*
* Load video to apply changes.
* We test if video's visibility has changed to avoid
* reloading the video even if we haven't reached a break point.
*/
function loadVideo() {
if (typeof pluginObject.$wrapper.load === 'function' && hasVisibilityChanged()) {
pluginObject.$wrapper.load();
}
}
/*
* A video's visibility is determined by its height.
* Set video height to "0" in CSS if you don't
* want it to be displayed for certain screen sizes.
*/
function isVideoVisible() {
var isVisible;
pluginObject.$wrapper.wasVisible = pluginObject.$wrapper.isVisible;
if (pluginObject.$wrapper.height() > 0) {
pluginObject.$wrapper.isVisible = true;
isVisible = true;
} else {
pluginObject.$wrapper.isVisible = false;
isVisible = false;
}
return isVisible;
}
function addSrc() {
var $videoSources = pluginObject.$wrapper.find('source');
$videoSources.each(function () {
var $source = $(this),
dataSrc = $source.attr(settings.dataSrc);
if (dataSrc) {
$source.attr('src', dataSrc);
}
});
}
function removeSrc() {
var $videoSources = pluginObject.$wrapper.find('source');
$videoSources.each(function () {
var $source = $(this);
$source.removeAttr('src');
});
}
function updateVideo() {
if (isVideoVisible()) {
addSrc();
} else {
removeSrc();
}
loadVideo();
}
function onResize() {
var debouncedUpdate;
debouncedUpdate = debounce(function () {
updateVideo();
}, 50);
$(window).on('resize', function () {
debouncedUpdate();
});
}
$.extend(Plugin.prototype, {
/**
* Initiate the plugin
*/
init: function () {
updateVideo();
onResize();
}
});
$.fn[pluginName] = function (options) {
return this.each(function () {
if (!$.data(this, "plugin_" + pluginName)) {
$.data(this, "plugin_" + pluginName, new Plugin(this, options));
}
});
};
}(jQuery));
<video class="responsive video-player" width="100%" autoplay loop muted>
<!--/* By adding the src attribute to the source element using JS, we
ensure the video file is not loaded when it's not visible (i.e. on mobile) */-->
<source data-src="http://videourl" type="video/mp4">
<p>Your browser does not support HTML5 video tag.</p>
</video>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment