How to lazy load images with jQuery
In this article, we are going to create a simple library which takes a selector (preferably class) and makes the images inside it lazy load. Lazy loading means that the user will request the resources (in this case, images) only when they are needed. In our case, this means when the user scrolls down enough. If the user scrolls to the place where the image is supposed to be, his browser will request the image and it will be displayed to him.
If he never scrolls down enough to see most of the images – his browser would have never requested them from our server.
How to make a lazy loader?
In our <head> tag, we just load jQuery.
<script src="https://code.jquery.com/jquery-1.11.3.min.js"></script>
In our <body> tag we create a container for the images and give it a class. Inside the container, we place as much images as we need.
<div class="load-img"> <img src="img/lazy.png" data-src="img/dodo.png" width="678" height="800" alt=""/> <img src="img/lazy.png" data-src="img/Dodo2.png" width="577" height="749" alt=""/> </div>
We have used the data-src attribute to hold the real src attribute of the image that has to be loaded there. All src attributes point to a small pure black image which serve as a placeholder for the actual images. We also set the width and height attributes to have the dimensions of the real image (the one whose path is store in the data-src attribute). We do not really have to put placeholders with the same image size but we just wanted to make it as smooth as if the image was really there.
Now, let us proceed with the lazyLoader library.
We create an object with an initialize method which takes a CSS-styles selector of the container(s) of the images and calls the revealWhenScrolled function once when the method is called and hooks up an event listener that will call revealWhenScrolled each time the user scrolls.
var lazyLoader; lazyLoader = { initialize: function (imgContainer) { var images = $(imgContainer).find("img"); this.revealWhenScrolled(images); $(document).on("scroll", function() { lazyLoader.revealWhenScrolled(images); } ); },
The revealWhenScrolled function loops over each image and if the viewport’s vertical position in the document is lower or at the level of the image – it replaces the image’s src attribute with its data-src attribute.
revealWhenScrolled: function (images) { for (var i = 0; i < images.length; i++) { var image = $(images[i]); if (this.isVisible(image)) { image.attr("src", image.attr("data-src")); } } },
Finally, we have the isVisible method which checks if the viewport’s vertical position in the document has reached or exceeded the image’s vertical position in the document.
isVisible: function (image) { return $(document).scrollTop() + $(window).height() >= image.offset().top; }
Finally, before we close our <body> tag (placing your scripts after the HTML optimizes the page’s loading speed) we load our lazyLoader library and initialize it:
<script src="js/lazyLoad.js"></script> <script> $(function() { lazyLoader.initialize('.load-img'); }) </script>
Now, all the images in the container(s) will load only when the user needs them! Easy as cake!
Tutorial Categories:
I always thought it implied some new js library. Thank you
Good However is it not possible to add the class directly to the image ?
Adding the Class to the image will make it easier to use with a CMS for example. If i develop a CMS, i can not ask my customer to create a div and embed the images in a div with a class but i can ask them to select the image and apply a class to it. So can your code work if not in a div and the class is applied directly to the image ?