Fork me on GitHub


the above lazyloaded after a one second timeout
lazyload images example "appearlazy"
all images from - scroll down

these images lazy loaded individually

the images in this parent container are loaded all at once

The images in this container are missing

A holding image or shim

An alternate image

An inline data image

No holding image

Both images missinge


appearlazy uses appear.js to lazy load images or divs that have an "appear" class. It works by switching a data-src attribute into the src as an image is identified as viewable.

Background images can be configured with a data-bkg attribute.

When applied to a div, appearlazy will search for elements within it with the right data-attribute or if none are found, on the div itself.

Images can also be lazy loaded on a simple timeout, using the data-delay attribute.

  (function() {
    'use strict';
    var nodes = [];

    function addClass(el) {
      if (el.classList) {
      } else {
        // IE9 compat
        el.className += ' ' + 'appeared';

    // set the image src or background attribute
    function doReveal(el) {
      var orig = el.getAttribute('src') || false;

      el.addEventListener('error', function handler(e) {
        // on error put back the original image if available (usually a placeholder)
        console.log('error loading image', e);
        if (orig) {
          el.setAttribute('src', orig);
        el.removeEventListener('error', handler); // hate this.

      var src = el.getAttribute('data-src');
      if (src) {
        el.setAttribute('src', src);
      src = el.getAttribute('data-bkg');
      if (src) { = 'url("' + src + '")';

    // find what element to work with, as we support containers of images
    function reveal(el) {
      if (el.hasChildNodes()) {
        // dealing with a container try and find children
        var els = el.querySelectorAll('[data-src], [data-bkg]');
        var elsl = els.length;
        if (elsl === 0) {
          // node has children, but none have the attributes, so reveal
          // the node itself (use case: div with a background)
        } else {
          for (var j = 0; j < elsl; j++) {
      } else {

    // reveal an image after a specified timeout
    function delayAppear(el, delay) {
      setTimeout(function() {
      }, delay);

    return {
      // function executed when dom is interactive
      init: function init() {
        // find all elements with the class "appear"
        var els = document.getElementsByClassName('appear');
        var elsl = els.length;
        //  put html elements into an array object to work with
        for (var i = 0; i < elsl; i += 1) {
          // some images are revealed on a simple timeout, instead of
          // viewport appears. These delays appears must have
          // the appear class on them directly
          var delay = els[i].getAttribute('data-delay');
          if (delay) {
            delayAppear(els[i], delay);
          } else {
      elements: nodes,
      // function to run when an element is determined to be in view
      appear: reveal,
      // larger bounds area for reveal images
      bounds: 200


"appeared" images can be fade transitioned into view using the following css

.appear[data-src], .appear[data-bkg], .appear [data-src], .appear [data-bkg] {
  opacity: 0;
  -webkit-transition: opacity 1s ease-in;
     -moz-transition: opacity 1s ease-in;
          transition: opacity 1s ease-in;
.appeared[data-src], .appeared[data-bkg], .appeared [data-src], .appeared [data-bkg] {
  opacity: 1;


source or minified