/** * Lazy Plugin * @version 2.3.4 * @author Bartosz Wojciechowski * @author David Deutsch * @license The MIT License (MIT) */ ;(function($, window, document, undefined) { /** * Creates the lazy plugin. * @class The Lazy Plugin * @param {Owl} carousel - The Owl Carousel */ var Lazy = function(carousel) { /** * Reference to the core. * @protected * @type {Owl} */ this._core = carousel; /** * Already loaded items. * @protected * @type {Array.} */ this._loaded = []; /** * Event handlers. * @protected * @type {Object} */ this._handlers = { 'initialized.owl.carousel change.owl.carousel resized.owl.carousel': $.proxy(function(e) { if (!e.namespace) { return; } if (!this._core.settings || !this._core.settings.lazyLoad) { return; } if ((e.property && e.property.name == 'position') || e.type == 'initialized') { var settings = this._core.settings, n = (settings.center && Math.ceil(settings.items / 2) || settings.items), i = ((settings.center && n * -1) || 0), position = (e.property && e.property.value !== undefined ? e.property.value : this._core.current()) + i, clones = this._core.clones().length, load = $.proxy(function(i, v) { this.load(v) }, this); //TODO: Need documentation for this new option if (settings.lazyLoadEager > 0) { n += settings.lazyLoadEager; // If the carousel is looping also preload images that are to the "left" if (settings.loop) { position -= settings.lazyLoadEager; n++; } } while (i++ < n) { this.load(clones / 2 + this._core.relative(position)); clones && $.each(this._core.clones(this._core.relative(position)), load); position++; } } }, this) }; // set the default options this._core.options = $.extend({}, Lazy.Defaults, this._core.options); // register event handler this._core.$element.on(this._handlers); }; /** * Default options. * @public */ Lazy.Defaults = { lazyLoad: false, lazyLoadEager: 0 }; /** * Loads all resources of an item at the specified position. * @param {Number} position - The absolute position of the item. * @protected */ Lazy.prototype.load = function(position) { var $item = this._core.$stage.children().eq(position), $elements = $item && $item.find('.owl-lazy'); if (!$elements || $.inArray($item.get(0), this._loaded) > -1) { return; } $elements.each($.proxy(function(index, element) { var $element = $(element), image, url = (window.devicePixelRatio > 1 && $element.attr('data-src-retina')) || $element.attr('data-src') || $element.attr('data-srcset'); this._core.trigger('load', { element: $element, url: url }, 'lazy'); if ($element.is('img')) { $element.one('load.owl.lazy', $.proxy(function() { $element.css('opacity', 1); this._core.trigger('loaded', { element: $element, url: url }, 'lazy'); }, this)).attr('src', url); } else if ($element.is('source')) { $element.one('load.owl.lazy', $.proxy(function() { this._core.trigger('loaded', { element: $element, url: url }, 'lazy'); }, this)).attr('srcset', url); } else { image = new Image(); image.onload = $.proxy(function() { $element.css({ 'background-image': 'url("' + url + '")', 'opacity': '1' }); this._core.trigger('loaded', { element: $element, url: url }, 'lazy'); }, this); image.src = url; } }, this)); this._loaded.push($item.get(0)); }; /** * Destroys the plugin. * @public */ Lazy.prototype.destroy = function() { var handler, property; for (handler in this.handlers) { this._core.$element.off(handler, this.handlers[handler]); } for (property in Object.getOwnPropertyNames(this)) { typeof this[property] != 'function' && (this[property] = null); } }; $.fn.owlCarousel.Constructor.Plugins.Lazy = Lazy; })(window.Zepto || window.jQuery, window, document); $(document).ready(function() { var sync1 = $("#sync1"); var sync2 = $("#sync2"); var slidesPerPage = 3; //globaly define number of elements per page var syncedSecondary = true; sync1.owlCarousel({ items: 1, slideSpeed: 2000, nav: true, autoplay: false, dots: true, loop: true, responsiveRefreshRate: 200, navText: ['', ''], }).on('changed.owl.carousel', syncPosition); sync2 .on('initialized.owl.carousel', function() { sync2.find(".owl-item").eq(0).addClass("current"); }) .owlCarousel({ items: slidesPerPage, dots: true, nav: true, smartSpeed: 200, slideSpeed: 500, slideBy: 1, //alternatively you can slide by 1, this way the active slide will stick to the first item in the second carousel responsiveRefreshRate: 100 }).on('changed.owl.carousel', syncPosition2); function syncPosition(el) { //if you set loop to false, you have to restore this next line //var current = el.item.index; //if you disable loop you have to comment this block var count = el.item.count - 1; var current = Math.round(el.item.index - (el.item.count / 2) - .5); if (current < 0) { current = count; } if (current > count) { current = 0; } //end block sync2 .find(".owl-item") .removeClass("current") .eq(current) .addClass("current"); var onscreen = sync2.find('.owl-item.active').length - 1; var start = sync2.find('.owl-item.active').first().index(); var end = sync2.find('.owl-item.active').last().index(); if (current > end) { sync2.data('owl.carousel').to(current, 100, true); } if (current < start) { sync2.data('owl.carousel').to(current - onscreen, 100, true); } } function syncPosition2(el) { if (syncedSecondary) { var number = el.item.index; sync1.data('owl.carousel').to(number, 100, true); } } sync2.on("click", ".owl-item", function(e) { e.preventDefault(); var number = $(this).index(); sync1.data('owl.carousel').to(number, 300, true); }); });