Your IP : 216.73.216.147


Current Path : /home/lejardintz/www/templates/as002085/js/
Upload File :
Current File : /home/lejardintz/www/templates/as002085/js/jquery.lazy.js

/*!
 * jQuery Lazy - v0.3.7
 * http://jquery.eisbehr.de/lazy/
 * http://eisbehr.de
 *
 * Copyright 2014, Daniel 'Eisbehr' Kern
 *
 * Dual licensed under the MIT and GPL-2.0 licenses:
 * http://www.opensource.org/licenses/mit-license.php
 * http://www.gnu.org/licenses/gpl-2.0.html
 *
 * jQuery("img.lazy").lazy();
 */

(function($, window, document, undefined)
{
    $.fn.lazy = function(settings)
    {
        "use strict";

        /**
         * settings and configuration data
         * @access private
         * @type {*}
         */
        var _configuration =
        {
            // general
			baseurl			: "",
            bind            : "load",
            threshold       : 500,
            fallbackWidth   : 2000,
            fallbackHeight  : 2000,
            visibleOnly     : true,
            appendScroll    : window,
            scrollDirection : "both",

            // delay
            delay           : -1,
            combined        : false,

            // attribute
            attribute       : "data-src",
            removeAttribute : true,
            handledName     : "handled",

            // effect
            effect          : "show",
            effectTime      : 0,

            // throttle
            enableThrottle  : false,
            throttle        : 250,

            // queue
            enableQueueing  : true,

            // callbacks
            beforeLoad      : null,
            onLoad          : null,
            afterLoad       : null,
            onError         : null,
            onFinishedAll   : null
        },

        /**
         * all given items by jQuery selector
         * @access private
         * @type {*}
         */
        _items = this,

        /**
         * a helper to trigger the onFinishedAll after all other events
         * @access private
         * @type {number}
         */
        _awaitingAfterLoad = 0,

        /**
         * visible content width
         * @access private
         * @type {number}
         */
        _actualWidth = -1,

        /**
         * visible content height
         * @access private
         * @type {number}
         */
        _actualHeight = -1,

        /**
         * queue timer instance
         * @access private
         * @type {null|number}
         */
        _queueTimer = null,

        /**
         * array of items in queue
         * @access private
         * @type {Array}
         */
        _queueItems = [],

        /**
         * identifies if queue actually contains the lazy magic
         * @access private
         * @type {boolean}
         */
        _queueContainsMagic = false;

        /**
         * initialize plugin - bind loading to events or set delay time to load all images at once
         * @access private
         * @return void
         */
        function _init()
        {
            // if delay time is set load all images at once after delay time
            if( _configuration.delay >= 0 ) setTimeout(function() { _lazyLoadImages(true); }, _configuration.delay);

            // if no delay is set or combine usage is active bind events
            if( _configuration.delay < 0 || _configuration.combined )
            {
                // load initial images
                _lazyLoadImages(false);

                // bind lazy load functions to scroll event
                _addToQueue(function()
                {
                    $(_configuration.appendScroll).bind("scroll", _throttle(_configuration.throttle, function()
                    {
                        _addToQueue(function() { _lazyLoadImages(false) }, this, true);
                    }));
                }, this);

                // bind lazy load functions to resize event
                _addToQueue(function()
                {
                    $(_configuration.appendScroll).bind("resize", _throttle(_configuration.throttle, function()
                    {
                        _actualWidth = _actualHeight = -1;
                        _addToQueue(function() { _lazyLoadImages(false) }, this, true);
                    }));
                }, this);
            }
        }

        /**
         * the 'lazy magic' - check all items
         * @access private
         * @param {boolean} allImages
         * @return void
         */
        function _lazyLoadImages(allImages)
        {
            // stop if no items where left
            if( !_items.length ) return;

            // helper to see if something was changed
            var loadedImages = false;

            for( var i = 0; i < _items.length; i++ )
            {
                (function()
                {
                    var item = _items[i], element = $(item);

                    if( _isInLoadableArea(item) || allImages )
                    {
                        var tag = _items[i].tagName.toLowerCase();

                        if( // image source attribute is available
                            element.attr(_configuration.attribute) &&
                            // and is image tag where attribute is not equal source 
                            ((tag == "img" && element.attr(_configuration.attribute) != element.attr("src")) ||
                            // or is non image tag where attribute is not equal background
                            ((tag != "img" && element.attr(_configuration.attribute) != element.css("background-image"))) ) &&
                            // and is not actually loaded just before
                            !element.data(_configuration.handledName))
                        {
                            loadedImages = true;

                            // mark element always as handled as this point to prevent double loading
                            element.data(_configuration.handledName, true);

                            // add item to loading queue
                            _addToQueue(function() { _handleItem(element, tag) }, this);
                        }
                    }
                })();
            }

            // when something was loaded remove them from remaining items
            if( loadedImages ) _addToQueue(function()
            {
                _items = $(_items).filter(function()
                {
                    return !$(this).data(_configuration.handledName);
                });
            }, this);
        }

        /**
         * load the given element the lazy way
         * @access private
         * @param {object} element
         * @param {string} tag
         * @return void
         */
        function _handleItem(element, tag)
        {
            // create image object
            var imageObj = $(new Image());

            // increment count of items waiting for after load
            ++_awaitingAfterLoad;

            // bind error event if wanted, otherwise only reduce waiting count
            if( _configuration.onError ) imageObj.error(function() { _triggerCallback(_configuration.onError, element); _reduceAwaiting(); });
            else imageObj.error(function() { _reduceAwaiting(); });

            // bind after load callback to image
            var onLoad = false;
            imageObj.one("load", function()
            {
                var callable = function()
                {
                    if( !onLoad )
                    {
                        window.setTimeout(callable, 100);
                        return;
                    }

                    // remove element from view
                    element.hide();

                    // set image back to element
                    if( tag == "img" ) element.attr("src", imageObj.attr("src"));
                    else element.css("background-image", "url(" + imageObj.attr("src") + ")");

                    // bring it back with some effect!
                    element[_configuration.effect](_configuration.effectTime);

                    // remove attribute from element
                    if( _configuration.removeAttribute ) element.removeAttr(_configuration.attribute);

                    // call after load event
                    _triggerCallback(_configuration.afterLoad, element);

                    // unbind event and remove image object
                    imageObj.unbind("load").remove();

                    // remove item from waiting cue and possible trigger finished event
                    _reduceAwaiting();
                };

                callable();
            });

            // trigger function before loading image
            _triggerCallback(_configuration.beforeLoad, element);

            // set source
            imageObj.attr("src", _configuration.baseurl+element.attr(_configuration.attribute));

            // trigger function before loading image
            _triggerCallback(_configuration.onLoad, element);
            onLoad = true;

            // call after load even on cached image
            if( imageObj.complete ) imageObj.load();
        }

        /**
         * check if the given element is inside the current view or threshold
         * @access private
         * @param {object} element
         * @return {boolean}
         */
        function _isInLoadableArea(element)
        {
            var viewedWidth  = _getActualWidth(),
                viewedHeight = _getActualHeight(),
                elementBound = element.getBoundingClientRect(),
                vertical     = // check if element is in loadable area from top
                               ((viewedHeight + _configuration.threshold) > elementBound.top) &&
                               // check if element is even in loadable are from bottom
                               (-_configuration.threshold < elementBound.bottom),
                horizontal   = // check if element is in loadable area from left
                               ((viewedWidth + _configuration.threshold) > elementBound.left) &&
                               // check if element is even in loadable are from right
                               (-_configuration.threshold < elementBound.right);

            if( _configuration.scrollDirection == "vertical" ) return vertical;
            else if( _configuration.scrollDirection == "horizontal" ) return horizontal;

            return vertical && horizontal;
        }

        /**
         * try to allocate current viewed width of the browser
         * uses fallback option when no height is found
         * @access private
         * @return {number}
         */
        function _getActualWidth()
        {
            if( _actualWidth >= 0 ) return _actualWidth;

            _actualWidth = window.innerWidth ||
                           document.documentElement.clientWidth ||
                           document.body.clientWidth ||
                           document.body.offsetWidth ||
                           _configuration.fallbackWidth;

            return _actualWidth;
        }

        /**
         * try to allocate current viewed height of the browser
         * uses fallback option when no height is found
         * @access private
         * @return {number}
         */
        function _getActualHeight()
        {
            if( _actualHeight >= 0 ) return _actualHeight;

            _actualHeight = window.innerHeight ||
                            document.documentElement.clientHeight ||
                            document.body.clientHeight ||
                            document.body.offsetHeight ||
                            _configuration.fallbackHeight;

            return _actualHeight;
        }

        /**
         * helper function to throttle down event triggering
         * @access private
         * @param {number} delay
         * @param {function} call
         * @return {function}
         */
        function _throttle(delay, call)
        {
            var _timeout, _exec = 0;

            function callable()
            {
                var elapsed = +new Date() - _exec;

                function run()
                {
                    _exec = +new Date();
                    call.apply(undefined);
                }

                _timeout && clearTimeout(_timeout);

                if( elapsed > delay || !_configuration.enableThrottle ) run();
                else _timeout = setTimeout(run, delay - elapsed);
            }

            return callable;
        }

        /**
         * reduce count of awaiting elements to 'afterLoad' event and fire 'onFinishedAll' if reached zero
         * @access private
         * @return void
         */
        function _reduceAwaiting()
        {
            --_awaitingAfterLoad;

            // if no items were left trigger finished event 
            if( !_items.size() && !_awaitingAfterLoad ) _triggerCallback(_configuration.onFinishedAll, null);
        }

        /**
         * single implementation to handle callbacks and pass parameter
         * @access private
         * @param {function} callback
         * @param {object} [element]
         * @return void
         */
        function _triggerCallback(callback, element)
        {
            if( callback )
            {
                if( element )
                    _addToQueue(function() { callback(element); }, this);
                else
                    _addToQueue(callback, this);
            }
        }

        /**
         * set next timer for queue execution
         * @access private
         * @return void
         */
        function _setQueueTimer()
        {
            _queueTimer = setTimeout(function()
            {
                _addToQueue();
                if( _queueItems.length ) _setQueueTimer();
            }, 2);
        }

        /**
         * add new execution to queue
         * @access private
         * @param {object} [callable]
         * @param {object} [context]
         * @param {boolean} [isLazyMagic]
         * @returns void
         */
        function _addToQueue(callable, context, isLazyMagic)
        {
            if( callable )
            {
                // execute directly when queue is disabled and stop queuing
                if( !_configuration.enableQueueing )
                {
                    callable.call(context || window);
                    return;
                }

                // let the lazy magic only be once in queue
                if( !isLazyMagic || (isLazyMagic && !_queueContainsMagic) )
                {
                    _queueItems.push([callable, context, isLazyMagic]);
                    if( isLazyMagic ) _queueContainsMagic = true;
                }

                if( _queueItems.length == 1 ) _setQueueTimer();

                return;
            }

            var next = _queueItems.shift();

            if( !next ) return;
            if( next[2] ) _queueContainsMagic = false;

            next[0].call(next[1] || window);
        }

        // set up lazy
        (function()
        {
            // overwrite configuration with custom user settings
            if( settings ) $.extend(_configuration, settings);

            // late-bind error callback to images if set
            if( _configuration.onError ) _items.each(function()
            {
                var item = this;
                _addToQueue(function()
                {
                    $(item).bind("error", function()
                    {
                        _triggerCallback(_configuration.onError, $(this));
                    });
                }, item);
            });

            // on first page load get initial images
            if( _configuration.bind == "load" ) $(window).load(_init);

            // if event driven don't wait for page loading
            else if( _configuration.bind == "event" ) _init();
        })();

        return this;
    };

    // make lazy a bit more case-insensitive :)
    $.fn.Lazy = $.fn.lazy;

})(jQuery, window, document);