lazySlider

A lightweight image carousel.

[Download jquery.lazyslider.1.2.1.min.js]

Usage

This plugin utilizes lazysizes from https://github.com/aFarkas/lazysizes for better image loading control. Simply include the plugin code and populate your container with images. Instantiate on DOM load with $(selector).lazyslider(); You can use data-bg on the element to preset the image backdrop color and data-speed to set the transition speed. Navigation and dimiss graphics are embedded. Swipe functionality added at the mobile-level.

Plugin Code

/*!
* jQuery LazySlider; version: 1.2.1 build: 20200203
* http://www.jawatradingcompany.com/plugins/lazySlider.php
* Copyright (c) 2020 Chris Bond; Dual licensed: MIT/GPL
*/

(function($) {
    "use strict";

    var wait = false;
    var request = new XMLHttpRequest();
   
    $.fn.lazyslider = function( options ) {
        var publicMethod = this;
        var next,prev,prepEnlargement,totalImages,imagesLoaded,$center;
        var $next = $('   ');
        var $prev = $('   ');
        var $close = $('   ');


        var data = {bg:"white"};
        var  ec,o,a,e,d,rinv;
        var ep = $('
0%
'); var $ac,$container,$minWidth; publicMethod.next = function () { $minWidth = $(".lazysliderImageContainer:empty:first").width(); if(!wait){ if($(".lazyslider-enlarged").length){ e = $(".lazyslider-enlarged"); e.css({opacity:.5}) ep.html("0%") } $ac.css({opacity:.5}) wait = true; $center.animate({width:$minWidth+"px"},data.speed,function(){ var offset = $center.width() + parseInt($center.css("marginLeft")) + parseInt($center.css("marginRight")); $center.removeClass("center"); var first = $container.find(".lazysliderImageContainer:has(img):first"); if($(".lazysliderImageContainer").length >= 9){ var firstImage = $container.find(".lazysliderImageContainer:has(img):eq(1)"); } else { var firstImage = $container.find(".lazysliderImageContainer:has(img):first"); } var cloned = firstImage.find("img").clone(true); var firstEmpty = $container.find(".lazysliderImageContainer:empty:first"); var lastEmpty = $container.find(".lazysliderImageContainer:empty:last"); var newEmpty = $('
') newEmpty.insertAfter(lastEmpty); firstEmpty.css({marginLeft:offset+"px"}) cloned.removeClass("lazyloaded"); lastEmpty.css({backgroundColor:data.bg}) cloned.appendTo(lastEmpty) cloned.addClass("lazyloaded"); first.css({opacity:0}) var c = Math.floor($container.find(".lazysliderImageContainer").length / 2); $center = $container.find(".lazysliderImageContainer").eq(c); $center.addClass("center"); publicMethod.prepEnlargement(); $container.find(".lazyslider-img").removeAttr("data-touchx"); firstEmpty.animate({marginLeft:-offset+"px"},data.speed,function(){ $ac.css({opacity:1}) first.remove(); firstEmpty.removeAttr("style"); wait = false; //$center.find("img").attr("data-orig-width", $center.find("img").width()) if($center.find("img").attr("data-width") < $minWidth + 20){ $center.find("img").attr("data-width", $minWidth); } $center.animate({width:$center.find("img").attr("data-width")+"px"},data.speed) if($(".lazyslider-enlarged").length){ if($center.find("img").data("url")){ window.open($center.find("img").data("url"), '_blank'); $(".lazyslider-enlarge-container, .lazyslider-img-details, .lazyslider-overlay, .lazyslider-enlarge-arrows").remove(); return; } var src = $center.find("img").attr("src"); ep.attr("data-src",src); ep.appendTo(ec); request.open('GET', src, true); request.send(null); } }); }) } }; publicMethod.prev = function () { $minWidth = $(".lazysliderImageContainer:empty:first").width(); if(!wait){ if($(".lazyslider-enlarged").length){ e = $(".lazyslider-enlarged"); e.css({opacity:.5}) ep.html("0%") } $ac.css({opacity:.5}) wait = true; $center.animate({width:$minWidth+"px"},data.speed,function(){ var offset = $center.width() + parseInt($center.css("marginLeft")) + parseInt($center.css("marginRight")); var mL = parseInt($center.css("marginLeft")); $center.removeClass("center"); var last = $container.find(".lazysliderImageContainer:has(img):last"); if($container.find(".lazysliderImageContainer").length >= 9){ var secondToLast = $container.find(".lazysliderImageContainer:has(img)").length-2; var lastImage = $container.find(".lazysliderImageContainer:has(img):eq("+secondToLast+")"); } else { var lastImage = $container.find(".lazysliderImageContainer:has(img):last"); } var cloned = lastImage.find("img").clone(true); var firstEmpty = $container.find(".lazysliderImageContainer:empty:first"); var lastEmpty = $container.find(".lazysliderImageContainer:empty:last"); var newEmpty = $('
') newEmpty.insertBefore(firstEmpty); firstEmpty.css({marginLeft:-offset+"px"}) cloned.removeClass("lazyloaded"); cloned.appendTo(firstEmpty) firstEmpty.css({backgroundColor:data.bg}) cloned.addClass("lazyloaded"); var c = Math.floor($container.find(".lazysliderImageContainer").length / 2)-1; $center = $container.find(".lazysliderImageContainer").eq(c); $center.addClass("center"); publicMethod.prepEnlargement(); $container.find(".lazyslider-img").removeAttr("data-touchx"); last.css({opacity:0}) firstEmpty.animate({marginLeft:offset+"px"},data.speed,function(){ $ac.css({opacity:1}) lastEmpty.remove(); last.replaceWith(lastEmpty); $(this).css({marginLeft:mL+"px"}) wait = false; //$center.find("img").attr("data-orig-width", $center.find("img").width()) if($center.find("img").attr("data-width") < $minWidth + 20){ $center.find("img").attr("data-width", $minWidth); } $center.animate({width:$center.find("img").attr("data-width")+"px"},data.speed) if($(".lazyslider-enlarged").length){ if($center.find("img").data("url")){ window.open($center.find("img").data("url"), '_blank'); $(".lazyslider-enlarge-container, .lazyslider-img-details, .lazyslider-overlay, .lazyslider-enlarge-arrows").remove(); return; } var src = $center.find("img").attr("src"); ep.attr("data-src",src); ep.appendTo(ec); request.open('GET', src, true); request.send(null); } }); }); } }; publicMethod.onProgress = $.throttle(100, function (event) { if (!event.lengthComputable) { return; } var loaded = event.loaded; var total = event.total; var progress = (loaded / total).toFixed(2); console.log(progress); if(progress<.5){ ep.show(); } ep.html(parseInt(progress * 100)+"%"); }) publicMethod.onComplete = function(event) { if(this.status == 200) { var reader = new FileReader(); reader.readAsDataURL(request.response); reader.onload = function(e) { $(".lazyslider-enlarged").attr('src', e.target.result); } } } publicMethod.onError = function(event) { } request.onprogress = publicMethod.onProgress; request.onload = publicMethod.onComplete; request.onerror = publicMethod.onError; publicMethod.prepEnlargement = function(){ var el = $center.find("img"); el.unbind().on("click",function(){ if($(this).data("url")){ window.open($(this).data("url"), '_blank'); return; } ep.attr("data-src",$(this).data("src")).hide(); ec= $('
'); o = $('
'); a = $ac.clone(true); e = $(''); a.addClass("lazyslider-enlarge-arrows").removeClass("lazyslider-arrow-container"); a.prependTo($("body")); a.fadeTo(1,0); o.prependTo($("body")); d = $('
'); $close.appendTo(d); d.prependTo($("body")); e.on("load",function(){ e.css({opacity:1}) setTimeout(function(){ep.hide('slow');},1000) a.fadeTo(500,1); d.fadeTo(500,1); }) ec.prependTo($("body")); e.appendTo(ec); ep.appendTo(ec); request.open('GET', $(this).data("src"), true); request.overrideMimeType('text/plain; charset=x-user-defined'); request.setRequestHeader('Content-type','application/x-www-form-urlencoded'); request.responseType = 'blob' request.send(null); e.add(o).add(d).on("click",function(){ e.css({opacity:0}) o.fadeTo(500,0,function(){$(this).remove();$("body").removeClass("lazyslider-overlayed");e.remove();ec.remove();}) d.fadeTo(500,0,function(){$(this).remove();}) a.fadeTo(500,0,function(){$(this).remove();}) }); }) } return this.each(function() { $container = $(this); $container.on("touchmove",function(e){ var tx = e.originalEvent.changedTouches[0].clientX; if(!$(this).attr("data-touchx")){ $(this).attr("data-touchx",tx) } }).on("touchend",function(e){ var tx = e.originalEvent.changedTouches[0].clientX; if($(this).attr("data-touchx") && $(this).attr("data-touchx") < tx){ $(this).removeAttr("data-touchx"); $prev.trigger("click"); } if($(this).attr("data-touchx") && $(this).attr("data-touchx") > tx){ $(this).removeAttr("data-touchx"); $next.trigger("click"); } }); $minWidth = $(".lazysliderImageContainer:empty:first").width(); for(var key in $container.data()){ data[key] = $container.data()[key]; } //console.log(data); totalImages = $container.find("img").length; imagesLoaded = 0; if(totalImages == 0){ $container.html("

LazySlider Error: You must populate this container with images.

"); return false; } $container.addClass("lazyslider-container"); $ac = $('
'); $container.find("img").each(function(){ $(this).attr("data-orig-width", $(this).data("width")) $(this).wrap('
'); }) $('
').appendTo($container); $('
').prependTo($container); $ac.insertAfter($container); $next.appendTo($ac); $prev.prependTo($ac); var c = Math.floor($container.find(".lazysliderImageContainer").length / 2); $center = $container.find(".lazysliderImageContainer").eq(c); $center.addClass("center"); $container.find(".lazyslider-img").on("load",function(){ imagesLoaded++; $(this).unbind(); $(this).parent().css({backgroundColor:data.bg}); if($(this).parent().hasClass("center")){ $ac.css({opacity:1}) } }) publicMethod.prepEnlargement(); $center.find(".lazyslider-img").on("load",function(){ responsiveSizing(); }) $center.animate({width:$center.find("img").attr("data-width")+"px"},data.speed) $ac.css({opacity:1}) $next.click(function () { publicMethod.next(); }); $prev.click(function () { publicMethod.prev(); }); function responsiveSizing(){ $container.find("img").each(function(){ var mw = $(".lazysliderImageContainer:empty:first").width(); var h = $(this).parent().height(); var w = $(this).width(); if($(window).width() <= 550 || $(window).height() <= 550){ $(this).attr("data-width",w); if($(this).parent().hasClass("center")){ $(this).parent().css({width:w+"px"}) } else { $(this).parent().css({width:mw+"px"}) } } else { $(this).attr("data-width",$(this).attr("data-orig-width")); if($(this).parent().hasClass("center")){ $(this).parent().css({width:$(this).attr("data-orig-width")+"px"}) } else { $(this).parent().css({width:mw+"px"}) } } }); } setTimeout(function(){ responsiveSizing(); },500); $(window).on("resize",function(){ responsiveSizing(); }) }); }; })(jQuery); /* * jQuery throttle / debounce - v1.1 - 3/7/2010 * http://benalman.com/projects/jquery-throttle-debounce-plugin/ * * Copyright (c) 2010 "Cowboy" Ben Alman * Dual licensed under the MIT and GPL licenses. * http://benalman.com/about/license/ */ (function(b,c){var $=b.jQuery||b.Cowboy||(b.Cowboy={}),a;$.throttle=a=function(e,f,j,i){var h,d=0;if(typeof f!=="boolean"){i=j;j=f;f=c}function g(){var o=this,m=+new Date()-d,n=arguments;function l(){d=+new Date();j.apply(o,n)}function k(){h=c}if(i&&!h){l()}h&&clearTimeout(h);if(i===c&&m>e){l()}else{if(f!==true){h=setTimeout(i?k:l,i===c?e-m:e)}}}if($.guid){g.guid=j.guid=j.guid||$.guid++}return g};$.debounce=function(d,e,f){return f===c?a(d,e,false):a(d,f,e!==false)}})(this);

CSS

.lazysliderImageContainer{
    min-width:250px;
    margin:0px 7.5px;
    position:relative;
    height:370px;
    left:0px;
    display:inline-grid;
    box-sizing: border-box;
    overflow:hidden;
    background-color:transparent;
    transition:background-color 0.5s ease,opacity 0.5s ease;
}
.lazyslider-img{
    opacity:0;
    width: 100%;
    position: absolute;
    min-height: 100%;
    transition: opacity 0.5s ease;
    object-fit: cover;
}
.lazyslider-error{
    text-align:center;
    color:red;
    padding:20px;
    font-size:12px;
    font-style:italic;
}
.lazyslider-img.lazyloaded{
    opacity: 0.3;
}
.lazysliderImageContainer.center .lazyslider-img.lazyloaded{
    opacity:1;
}
.lazyslider-container{
    padding: 32px 0px 0px 0px;
    position:relative;
    display:grid;
    flex-flow: nowrap;
    justify-content: center;
    overflow:hidden;
    grid-auto-flow: column;
}
.lazyslider-arrow-container{
    position:relative;
    display:flex;
    flex-flow: nowrap;
    justify-content: center;
    margin:20px 0px;
    opacity:0;
    transition:opacity 0.5s ease;
}
.lazysliderarrow{
    height: 20px;
    cursor:pointer;
    margin:0px 15px;
}
.lazyslider-enlarged{
    height: fit-content;
    width: 100vw;
    position: absolute;
    z-index: 99999;
    left: 50%;
    opacity: 0;
    cursor: pointer;
    transition: opacity 0.5s ease,height 0.5s ease,width 0.5s ease;
    object-fit: contain;
    transform: translate(-50%,-50%);
    top: 50%;
}
.lazyslider-enlarge-progress{
    height: 50px;
    width: 50%;
    text-align: center;
    position: absolute;
    z-index: 999999;
    left: 50%;
    top: 50%;
    transform: translate(-50%,-50%);
    font-size:50px;
    color:white;
}
.lazyslider-overlay {
    position: fixed;
    width: 100%;
    height: 100%;
    background: #000;
    z-index: 9999;
    left: 0%;
    top: 0%;
    cursor: pointer;
}
.lazyslider-overlayed{
    overflow:hidden;
}
.lazyslider-img-details {
    position: fixed;
    width: 100%;
    height: 10%;
    z-index: 9999;
    left: 50%;
    top: 0%;
    text-align: center;
    z-index: 999999;
    transform: translate(-50%,0%);
    padding: 5px;
    background-color: #fefefe0d;
    opacity:0;
    cursor:pointer;
}
.lazyslider-img-details svg{
    width: 20px;
    position: absolute;
    transform: translate(-50%, -50%);
    top: 50%;
    left: 50%;
}
.lazyslider-enlarge-container {
    height: 100vh;
    overflow: hidden;
    width: 100vw;
    position: fixed;
    top: 0px;
    left: 0px;
    z-index: 99999;
}
.lazyslider-enlarge-arrows {
    position: fixed;
    width: 100%;
    height: 10%;
    z-index: 9999;
    left: 50%;
    bottom: 0%;
    text-align: center;
    z-index: 999999;
    transform: translate(-50%,0%);
    padding: 5px;
    background-color: #fefefe0d;
    opacity:0;
    cursor:pointer;
}
.lazyslider-enlarge-arrows .lazysliderarrow {
    position: relative;
    transform: translate(0%,-50%);
    top: 50%;
}
.lazyslider-close-enlarge{
    height:20px;
}