Elements loaded

SlothyLoader

This is a fork of the acclaimed LaziestLoader by Josh Williams. It uses the same HTML conventions, but doesn't depend on jQuery.

Try SlothyLoader v2.0.0

  1. Development Version
  2. Production Version

Image Prep

Your web-ready files need to be structured so that the name or path includes the width or a slug that represents the width.

Examples

    • /images/pony-1300.jpg
    • /images/pony-900.jpg
    • /images/pony-640.jpg
    • /images/pony/1300.jpg
    • /images/pony/900.jpg
    • /images/pony/640.jpg
    • /images/1300/PONY-1300.jpg
    • /images/900/PONY-900.jpg
    • /images/640/PONY-640.jpg
    • /images/pony-large.jpg
    • /images/pony-medium.jpg
    • /images/pony-small.jpg
    • /images/pony/large.jpg
    • /images/pony/medium.jpg
    • /images/pony/small.jpg

Retina

Retina images are also supported with either pattern. You can use whatever naming convention you like to specify the retina source.

    • /images/pony-1300@2x.jpg
    • /images/pony-900@2x.jpg
    • /images/pony-640@2x.jpg
    • /images/retina-large/pony.jpg
    • /images/retina-medium/pony.jpg
    • /images/retina-small/pony.jpg

Retina 3x

iPhone 6/6S/7 Plus devices, as well as a number of Android devices, now have a pixel ratio of 3 or more. SlothyLoader supports this higher ratio, when devicePixelRatio is detected to be above 2, and you can use the naming convention you like to specify that retina 3x source.

    • /images/pony-1300@3x.jpg
    • /images/pony-900@3x.jpg
    • /images/pony-640@3x.jpg
    • /images/retina3x-large/pony.jpg
    • /images/retina3x-medium/pony.jpg
    • /images/retina3x-small/pony.jpg

HTML/CSS Prep

Your image element should include a default image. A 1x1 transparent GIF or PNG will do. You can also use a base64-encoded image as your src attribute, such as data:image/gif;base64,R0lGODlhCgAKAIAAAB8fHwAAACH5BAEAAAAALAAAAAAKAAoAAAIIhI+py+0PYysAOw==. You may also want to add a class to simplify your query selector in a moment. By default, elements with class "dvz-lazy" are lazy-loaded when calling slothyLoader without a selector value in its options.

<img class="dvz-lazy" src="img/transparent.gif">

SlothyLoader works by finding the best-sized source image to match the target image element's current width. Since "img" elements are inline elements, they'll only have as much width at the current image, which will most likely be very small, like a 1px transparent gif. To ensure the plugin works correctly, you need to make sure the "img" element reports the width you want it to be. One way is to force it to fill its container element with CSS.

img.dvz-lazy{ display: block; width: 100%; }

Example Usage

Non-responsive

The most basic method simply sets the src attribute as the element enters the viewport.

// html
<img class="dvz-lazy" src="img/transparent.gif" data-src="http://dummyimage.com/1400x700/753e75/fff.png">

// js
slothyLoader({selector: ".dvz-lazy"})
            

Non-responsive w/ Retina

Specify a standard and an optional retina image.

// html
<img class="dvz-lazy" src="img/transparent.gif" data-src="http://dummyimage.com/1400x700/2a2a2a/fff.png" data-src-retina="http://dummyimage.com/2800x1400/2a2a2a/fff.png">

// js
slothyLoader({selector: ".dvz-lazy"})
            

Non-responsive w/ Retina, smaller element

Basic example always loads the same image, regardess of element width.

// html
<img class="dvz-lazy" src="img/transparent.gif" data-src="http://dummyimage.com/1400x700/3a3a3a/fff.png" data-src-retina="http://dummyimage.com/2800x1400/3a3a3a/fff.png">

// js
slothyLoader({selector: ".dvz-lazy"})
            

Non-responsive w/ Retina 3x

Specify a standard image, an optional retina image at double the original resolution, and an optional retina 3x image at three times the original resolution. If you don't specify a regular retina image (2x), then the standard image will load on retina screens (which we consider to be anything that has a devicePixelRatio above 1). You can force a 3x device pixel ratio by using your device toolbar in your browser's dev tools.

// html
<img class="dvz-lazy" src="img/transparent.gif" data-src="http://dummyimage.com/1400x700/3a3a3a/fff.png" data-src-retina="http://dummyimage.com/2800x1400/3a3a3a/fff.png" data-src-retina3x="http://dummyimage.com/4200x2100/3a3a3a/fff.png">

// js
slothyLoader({selector: ".dvz-lazy"})
            

Responsive

Go beyond a single source by providing a URL that has a width as part of the path or name. This example works with retina patterns too.

// html
<img class="dvz-lazy" src="img/transparent.gif" data-pattern="img/ar-{{size}}.jpg" data-widths="[320, 900, 1500]">

// js
slothyLoader({selector: ".dvz-lazy"})
            

Responsive, smaller element

Load a smaller image, if possible.


// html
<img class="dvz-lazy" src="img/transparent.gif" data-pattern="img/ar-{{size}}.jpg" data-widths="[320, 900, 1500]">

// js
slothyLoader({selector: ".dvz-lazy"})
            

Responsive w/ Slugs

You can select a sized image that doesn't use the width value in the file name or path.


// html
<img class="dvz-lazy" src="img/transparent.gif" data-pattern="img/ar2-{{size}}.jpg" data-widths='[{"size":320,"slug":"small"}, {"size":900, "slug":"medium"}, {"size":1500, "slug":"large"}]'>

// js
slothyLoader({selector: ".dvz-lazy"})
            

Callback

Pass in a callback to excute custom code after the src attribute has been changed. That's how the updating "elements loaded" bar below works.

//html
<img class="callback" src="img/transparent.gif" data-src="http://dummyimage.com/1400x700/5a5a5a/fff.png">

// js
var totalLoaded = 0;
slothyLoader({ selector: "img.callback", threshold: 100}, function() {
    totalLoaded += 1;
    document.getElementById("total").innerHTML = totalLoaded;
});
                

Custom Source Function

Need fancier logic to determine the source path? You can write your own.

//html
<img class="custom" src="img/transparent.gif">

// js
slothyLoader({
    selector: "img.custom",
    threshold: 100,
    getSource: function($el) {
        var width = $el.offsetWidth;
        var height = Math.round(width * 0.5625);
        return 'http://placekitten.com/'+width+'/'+height;
    }
});
                

Best Fit

The best-fit method used internally can also be used in your callbacks and custom source functions. Pass in a target width and an array of possible values to find the best value.

//html
<img class="bestfit" src="img/transparent.gif">

// js
slothyLoader({
    selector: "img.bestfit",
    threshold: 100,
    getSource: function($el) {
        var width = slothyLoader.bestFit($el.offsetWidth, [200, 700, 900, 1200]);
        var height = Math.round(width * 0.5625);
        return "http://placekitten.com/" + width + "/" + height;
    }
});
                

Video

Images aren't the only things with 'src' attributes. Try a video.


// html
<video class="dvz-lazy" autoplay loop data-pattern="examples/earth-{{size}}.mp4" data-widths="[640, 960, 1280]"></video>

// js
slothyLoader({selector: ".dvz-lazy"})
            

Set Element Height Programmatically

Often in responsive applications it's useful to set the height of an element before the source is loaded so the element will pre-fill the correct amount of space. In this example, because iFrames also have src attributes but need their sizes specified to be useful, we'll set the height via the plugin. The height is determined by multipling the element width by the 'data-ratio' vaule. Note: This example will not be responsive because the iFrame content from YouTube isn't smart enough to repsond to the changing viewport.

// html
<iframe class="iframe" data-src="//www.youtube.com/embed/c8aFcHFu8QM" data-ratio="0.5625" frameborder="0" allowfullscreen></iframe>

// js
slothyLoader({selector: ".iframe", threshold: 300, setHeight: true})
                

Completely Custom Behavior /w Callback

Need more control than custom source path generation? For example, you might want to completely rewrite the contents of your element. You can have your callback do all the work, sidestepping much of SlothyLoader's functionality.

// html
<div class="override"></div>

// js
slothyLoader({
    selector: "div.override",
    threshold: 100,
    setSourceMode: false // this is the important bit!
}, function() {
    cb.call(this);
    var height = Math.ceil(this.offsetWidth * 0.5625);
    this.innerHTML = '<p style="text-align:center; height: '+height+'px; line-height:'+height+'px;-webkit-animation: pulse 10s infinite alternate;">Boom!</p>'
});
                

Options

In addition to the "Custom Source Function" using `getSource` example above, there are other optional behaviors that can be configured in the options object.

threshold

By default, images are only loaded when the user scrolls to them and they became visible on the screen.

If you want your images to load earlier than that, lets say 200px before they appear on the screen, specify the threshold in the options object.

slothyLoader({selector:"img", threshold: 200});

scrollThrottle

To increase performance, the position of lazy loading elements are only checked every 250ms while scrolling. If you need to perform the check more often, lower the number. If scroll performance is an issue -- likely if there are lots of elements -- increase the number.

slothyLoader({selector:"img", scrollThrottle: 300});

sizeOffsetPercent

The crop selection logic works by picking the image that is greater than or equal to the size of the current element. If you prefer to scale smaller images into larger elements, set this between 0 and 100, where the value is the percent width of the containing element you want to subtract from the math logic. The bigger the number, the smaller the image that'll be selected.

slothyLoader({selector:"img", sizeOffsetPercent: 10});

sizePattern

The regular expression used to search your string, to be replaced by the width number or slug. The default is `/{{SIZE}}/ig`, which finds the string `size`, regardless of case, inside of '{' style double brackets. Example: `/path/name-{{size}}.jpg`. Changing this option is useful if, for example, you have Mustache-style templates rendered on the server that would also match the default laziestloader.js pattern and be rendered blank before our client code runs. Many characters have special meaning and can't be used. A nice alternal pattern is:

slothyLoader({selector:"img", sizePattern: /%size%/ig});

setSourceMode

In most cases, the plugin needs to set the source attribute of the element. If you want to use the plugin in ways that don't involve simply setting a source attribute, set `setSourceMode` to false and use the callback to completely manage the behavior of the element on trigger.

<div><p>Replace me</p></div>

slothyLoader({
    selector: "div",
    setSourceMode: false
}, function(){
    this.innerHTML = '<div><p>New content</p></div>'
});
        

Trigger

You can trigger element loading without scrolling the element into view.

slothyLoader({selector: ".dvz-lazy"})
var slothyloaderEv = new CustomEvent('slothyloader');
var $elements = document.querySelectorAll('.dvz-lazy')
for (var i = 0; i < $elements.length; ++i) {
    var $el = $elements[i];
    $el.dispatchEvent(slothyloaderEv)
}
        

Release History

2.0.0

1.0.0

Credits

SlothyLoader is a lazy loader sans jQuery, forked from LaziestLoader by Josh Williams at release 0.7.3 (2016-01-03). He said he was inspired by Luís Almeida's unveil

As of March 6, 2019, the Intersection Observer API is used to detect when an element enters the viewport, when available. If unavailable, the trigger happens via event listeners and checking the viewport, as with the previous versions. Usage API stays the same.

License

TBD