Responsive Lazy-load Iframes With Vanilla JavaScript

Category: Javascript , Layout | March 19, 2016
Author: kerns
Views Total: 2,607
Official Page: Go to website
Last Update: March 19, 2016
License: MIT

Preview:

Responsive Lazy-load Iframes With Vanilla JavaScript

Description:

A vanilla JavaScript library used to make your iframe responsive by automatically adjusting the height and width depending on its inner content and the screen size. Great for Youtube video and Instagram photo embed.

How to use it:

Include the lazysizes.js to delay the loading of iframe content.

<script src='//cdnjs.cloudflare.com/ajax/libs/lazysizes/1.4.0/lazysizes.min.js'></script>

Insert content into your iframes using ‘data-src’ attribute like this:

<iframe allowtransparency="true" frameborder="0" height="710" scrolling="no" data-src="//instagram.com/p/zkOqETkZjI/embed/" width="612" class="lazyload"></iframe>

The core JavaScript function:

window.responsiveIframes = {
    defaults: {
    width: 610,
    extraHeight: 80,
    breakpoint: 620,
    fullWidth: true, // If true, iFrame will always have a width of 100% until it reaches maxWidth
    maxWidth: 800, // Only works when fullWidth is true. Sets CSS max-width to this value.
    src: ['instagram.com'],
    lazysizes: true // Compatible with lazysizes
    },

    options: {},
    frames: [],
    initialized: false,

    init: function(param_options) {
        this.frames = [];

        if (arguments.length === 1 && typeof param_options === 'object') {
            this.options = this.helpers.extend(this.defaults, param_options);
        } else {
            this.options = this.helpers.extend(this.defaults, {});
        }

        this.initialized = true;

        // Attach listeners to resize iFrame with window.
        window.addEventListener("load", function() {
            window.responsiveIframes.resizeFrames();
        });
        window.addEventListener("resize", function() {
            window.responsiveIframes.resizeFrames();
        });

    },
    resizeFrames: function() {
        if (!this.initialized) {
            this.init();
        }

        if (this.frames.length === 0) {
            this.frames = this.helpers.getIframes(this.options.src);
        }

        for (var i = 0; i < this.frames.length; i++) {
            this.resizeFrame(this.frames[i]);
        }
    },
    resizeFrame: function(elem) {
        var width;
        var windowWidth = this.helpers.windowWidth();
        var newHeight;

        if (this.options.fullWidth) {
            elem.style.width = '100%';
            elem.style.maxWidth = this.options.maxWidth + 'px';
        } else {
            if (windowWidth <= this.options.breakpoint) {
                elem.style.width = '100%';
            } else {
                elem.style.width = this.options.width.toString(10) + 'px';
            }
        }

        width = elem.offsetWidth;

        newHeight = Math.round(width + this.options.extraHeight);
        elem.style.height = newHeight.toString(10) + 'px';
    },
    helpers: {
        windowWidth: function() {
            var docElemProp = window.document.documentElement.clientWidth;
            var body = window.document.body;
            return window.document.compatMode === "CSS1Compat" && docElemProp || body && body.clientWidth || docElemProp;
        },
        extend: function(obj, extObj) {
            if (arguments.length > 2) {
                for (var a = 1; a < arguments.length; a++) {
                    this.extend2(obj, arguments[a]);
                }
            } else {
                for (var i in extObj) {
                    obj[i] = extObj[i];
                }
            }
            return obj;
        },
        getInstagramIframes: function() {
            var matchingElements = [];
            var allElements = document.getElementsByTagName('iframe');

            for (var i = 0; i < allElements.length; i++) {
                var src = allElements[i].getAttribute('src');
                if (src !== null && src.indexOf('instagram.com') !== -1) {
                    matchingElements.push(allElements[i]);
                }
            }

            return matchingElements;
        },
        getIframes: function(param_src) {
            var matchingElements = [];
            var allElements = document.getElementsByTagName('iframe');

            for (var i = 0; i < allElements.length; i++) {
                var src = allElements[i].getAttribute('src');

                if (src === null || (typeof src === 'string' && src.length === 0)) {
                    src = allElements[i].getAttribute('data-src');
                }

                if (src !== null) {
                    if (Array.isArray(param_src)) {
                        for (var j = 0; j < param_src.length; j++) {
                            if (src.indexOf(param_src[j]) !== -1) {
                                matchingElements.push(allElements[i]);
                            }
                        }
                    } else {
                        if (src.indexOf(param_src) !== -1) {
                            matchingElements.push(allElements[i]);
                        }
                    }
                }
            }

            return matchingElements;
        }
    }

};

Initialize with single domain:

window.responsiveIframes.init({src: 'instagram.com'});

Initialize with Multi-domains:

window.responsiveIframes.init({
  src: ['instagram.com', 'youtube.com'],
});

 

You Might Be Interested In:


Leave a Reply