How to Lazy Load div background images

Viewed 156933

As many of you know it is widely used to lazy load images.

Now i want to use this as lazy load div background images.

How can i do that ?

I am currently able to use http://www.appelsiini.net/projects/lazyload that plugin

So i need to modify it in a way that it will work with div backgrounds

Need help. Thank you.

The below part i suppose lazy loads images

$self.one("appear", function() {
    if (!this.loaded) {
        if (settings.appear) {
            var elements_left = elements.length;
            settings.appear.call(self, elements_left, settings);
        }
        $("<img />")
            .bind("load", function() {
                $self
                    .hide()
                    .attr("src", $self.data(settings.data_attribute))
                    [settings.effect](settings.effect_speed);
                self.loaded = true;

                /* Remove image from array so it is not looped next time. */
                var temp = $.grep(elements, function(element) {
                    return !element.loaded;
                });
                elements = $(temp);

                if (settings.load) {
                    var elements_left = elements.length;
                    settings.load.call(self, elements_left, settings);
                }
            })
            .attr("src", $self.data(settings.data_attribute));
    }
});

Jquery plugin lazy load

13 Answers

Mid last year 2020 web.dev posted an article that shared some new ways to do this with the the new IntersectionObserver which at the time of writing this answer is supported in all major browsers. This will allow you to use a very light weight background image, or background color placeholder while you wait for the image to come to the edge of the viewport and then it is loaded.

CSS

.lazy-background {
  background-image: url("hero-placeholder.jpg"); /* Placeholder image */
}

.lazy-background.visible {
  background-image: url("hero.jpg"); /* The final image */
}

Javascript

document.addEventListener("DOMContentLoaded", function() {
  var lazyBackgrounds = [].slice.call(document.querySelectorAll(".lazy-background"));

  if ("IntersectionObserver" in window) {
    let lazyBackgroundObserver = new IntersectionObserver(function(entries, observer) {
      entries.forEach(function(entry) {
        if (entry.isIntersecting) {
          entry.target.classList.add("visible");
          lazyBackgroundObserver.unobserve(entry.target);
        }
      });
    });

    lazyBackgrounds.forEach(function(lazyBackground) {
      lazyBackgroundObserver.observe(lazyBackground);
    });
  }
});

It's been a moment that this question is asked, but this doesn't mean that we can't share other answers in 2020. Here is an awesome plugin with jquery:jQuery Lazy

The basic usage of Lazy:

HTML

<!-- load background images of other element types -->
<div class="lazy" data-src="path/to/image.jpg"></div>
enter code here

JS

 $('.lazy').Lazy({
    // your configuration goes here
    scrollDirection: 'vertical',
    effect: 'fadeIn',
    visibleOnly: true,
    onError: function(element) {
        console.log('error loading ' + element.data('src'));
    }
});

and your background images are lazy loading. That's all!

To see real examples and more details check this link lazy-doc.

Without jQuery

HTML

background-image: url('default-loading-image');

data-src="image-you-want-to-load"

<div class="ajustedBackground"  style="background-image: url('default-loading-image');" data-src="image-you-want-to-load"><div>

var tablinks = document.getElementsByClassName("ajustedBackground");
    for (i = 0; i < tablinks.length; i++) {
      var lazy = tablinks[i];
      var src = lazy.dataset.src;

      lazy.style.backgroundImage =  'url("'+src+'")';
    }
.ajustedBackground{
  width: 100%;
  height: 300px;
  background-size: 100%;
  border-radius: 5px;
  background-size: cover;
  background-position: center;
  position: relative;
}
<div class="ajustedBackground"  style="background-image: url('https://monyo.az/resources/img/ezgif-6-b10ea37ef846.gif');" data-src="https://monyo.az/resources-qrcode/img/Fathir_7%201.png"><div>

Finds all ajustedBackground classname in html and load image from data-src

function lazyloadImages(){
    var tablinks = document.getElementsByClassName("ajustedBackground");
    for (i = 0; i < tablinks.length; i++) {
      var lazy = tablinks[i];
      var src = lazy.dataset.src;

      lazy.style.background =  'url("'+src+'")';
    }

}

Using jQuery I could load image with the check on it's existence. Added src to a plane base64 hash string with original image height width and then replaced it with the required url.

$('[data-src]').each(function() {
  var $image_place_holder_element = $(this);
  var image_url = $(this).data('src');
  $("<div class='hidden-class' />").load(image_url, function(response, status, xhr) {
    if (!(status == "error")) {
      $image_place_holder_element.removeClass('image-placeholder');
      $image_place_holder_element.attr('src', image_url);
    }
  }).remove();
});

Of course I used and modified few stack answers. Hope it helps someone.

This is an AngularJS Directive that will do this. Hope it helps someone

Usage:

<div background-image="{{thumbnailUrl}}"></div>

Code:

import * as angular from "angular";

export class BackgroundImageDirective implements angular.IDirective {

    restrict = 'A';

    link(scope: angular.IScope, element: angular.IAugmentedJQuery, attrs: angular.IAttributes) {
     
        var backgroundImage = attrs["backgroundImage"];

        let observerOptions = {
            root: null,
            rootMargin: "0px",
            threshold: []
        };

        var intersectionCallback: IntersectionObserverCallback = (entries, self) => {

            entries.forEach((entry) => {
                let box = entry.target as HTMLElement;

                if (entry.isIntersecting && !box.style.backgroundImage) {
                    box.style.backgroundImage = `url(${backgroundImage})`;
                    self.disconnect();
                }
            });
        }

        var observer = new IntersectionObserver(intersectionCallback, observerOptions);
        observer.observe(element[0]);
    }

    static factory(): angular.IDirectiveFactory {
        return () => new BackgroundImageDirective();
    }
}
<div class="lazy" data-bg="img/bmw_m1_hood.jpg" style="width: 765px; height: 574px;"></div>
    
var lazyLoadInstance = new LazyLoad({
  load_delay: 100,
  effect : "fadeIn"
});

using the vanilla lazyload https://www.npmjs.com/package/vanilla-lazyload

Related