; (function () { 'use strict'; /** * Play videos based on scroll position * @namespace */ sh.libs.videoDefer = (function ($) { var name = 'videoDefer'; /** * The threshold for when videos in view should be played * @private * @memberof sh.libs.videoDefer * @constant {number} */ var threshold = 200; /** * The array for all the videos to be played * @private * @memberof sh.libs.videoDefer * @type {array} */ var videos = []; /** * Check to see if scroll-listener has been added * @private * @memberof sh.libs.videoDefer * @type {bool} */ var scrollListenerAdded = false; /** * Plays a video with <code>data-video-defer="view"</code> attribute if it's within the viewport threshold * @private * @memberof sh.libs.videoDefer */ function playVideosInView() { var offset = $(document).scrollTop() + $(window).height() + threshold; videos.each(function (i, video) { if (video !== null) { if ($(video).offset().top < offset) { video.play(); // Take it away! videos[i] = null; $(video).attr('data-is-played', 'true'); } } }); } /** * Find videos in document that haven't been played yet * @private * @memberof sh.libs.videoDefer */ function findVideos() { videos = $('[data-video-defer="view"]:not([data-is-played="true"])'); } /** * Bind scroll-listener * @private * @memberof sh.libs.videoDefer */ function bindScroll() { scrollListenerAdded = true; $(window).on('scroll', function () { window.requestAnimationFrame(playVideosInView); }); } /** * Initialize the component * @public * @memberof sh.libs.videoDefer */ function init() { if (!sh.utils.isInitialized($('body'), name)) { if (document.readyState === 'complete') { playVideosInView(); } else { window.addEventListener('load', function () { setTimeout(function () { playVideosInView(); }, 0); }); } // Find videos in document findVideos(); // Bind scroll if(videos.length && !scrollListenerAdded) { bindScroll(); } // Set component as initialized sh.utils.initialized($('body'), name); } } /** * Reflow the component * @public * @memberof sh.libs.videoDefer */ function reflow() { if (!scrollListenerAdded) { bindScroll(); } findVideos(); playVideosInView(); } return { init: init, reflow: reflow }; })(jQuery); })();