How to Implement lazy image loading plug-in using Javascript
Various forums on the Internet, especially some image websites, adopt a lazy loading method when loading images. The specific manifestation is that when a page is requested, only images in the visible area are loaded, while images in other areas are not loaded. These images are dynamically loaded only when they appear in the visible area, this saves network bandwidth and increases the loading speed for the first time. The specific implementation technology is not complicated. The following describes the implementation technology respectively.
The lazy loading of Web images is to read the img element, then obtain the value of the data-src (which can also be agreed to be another property name) attribute of the img element, and assign the img src, this allows you to dynamically load images.
Note that img does not set the src attribute during initialization, because even if src = ''is set, the browser will try to load the image.
A simple image lazy loading involves two aspects.
1. HTML conventions
First, we need to add the specified class to the img element that is prepared to implement lazyload. Here, it is m-lazyload and img src is assigned to the data-src attribute.
Example:
2. JavaScript implementation
Dynamic Loading is divided into the following steps. Each step is split into independent functions.
1. Add page rolling listening events
window.addEventListener('scroll', _delay, false); function _delay() { clearTimeout(delay); delay = setTimeout(function () { _loadImage(); }, time);}
2. When a listener event is triggered, the _ loadImage function is executed to load images.
function _loadImage() { for (var i = imgList.length; i--;) { var el = imgList[i]; if (_isShow(el)) { el.src = el.getAttribute('data-src'); el.className = el.className.replace(new RegExp("(\\s|^)" + _selector.substring(1, _selector.length) + "(\\s|$)"), " "); imgList.splice(i, 1); } }}
Although the _ loadImage function is executed, we need to know which images need to be loaded. What is the basis of the judgment here?
The basis is to determine whether the image is in the visible area of the current window. Here we encapsulate a _ isShow function to implement
function _isShow(el) { var coords = el.getBoundingClientRect(); return ( (coords.top >= 0 && coords.left >= 0 && coords.top) <= (window.innerHeight || document.documentElement.clientHeight) + parseInt(offset));}
Since then, the closed loop of image loading has formed
When a page rolling event is triggered, click attach image to determine whether the image is in the visible area. Then, the value of data-src is dynamically assigned to the image.
Is it too simple?
This is the case !!!
It's so easy to extend.
Who like to add custom parameters?
Supports iScroll. iScroll is a high-performance, low resource usage, no dependency, and multi-platform javascript rolling plug-in.
Here we have made some optimizations.
Remove the selector after the image is loaded to avoid repeated judgment.
Cache img element combination to reduce dom element query performance loss
Extended prototype to add the getNode method, supporting lazy loading of paging data (because we cache dom elements before)
OK! Show me the code!
(Function () {var imgList = [], // delay of all img element sets on the page, // setTimeout object offset, // offset, used to specify the distance between an image and the visible area, loading time, // delay loading time _ selector; // The default value of the selector is. m-lazyload function _ isShow (el) {var coords = el. getBoundingClientRect (); return (coords. top> = 0 & coords. left> = 0 & coords. top) <= (window. innerHeight | document.doc umentElement. clientHeight) + parseInt (offset);} function _ loadImage () {for (var I = imgList. length; I --;) {var el = imgList [I]; if (_ isShow (el) {el. src = el. getAttribute ('data-src'); el. className = el. className. replace (new RegExp ("(\ s | ^)" + _ selector. substring (1, _ selector. length) + "(\ s | $)"), ""); imgList. splice (I, 1) ;}}function _ delay () {clearTimeout (delay); delay = setTimeout (function () {_ loadImage () ;}, time );} function ImageLazyload (selector, options) {var defaults = options ||{}; offset = defaults. offset | 0; time = defaults. time | 250; _ selector = selector | '. m-lazyload '; this. getNode (); _ delay (); // prevents the touch event from being triggered for the first time, and triggers the load function if (ults. iScroll) {defaults. iScroll. on ('scroll ', _ delay); defaults. iScroll. on ('rollend', _ delay);} else {window. addEventListener ('scroll ', _ delay, false) ;}} ImageLazyload. prototype. getNode = function () {imgList = []; var nodes = document. querySelectorAll (_ selector); for (var I = 0, l = nodes. length; I <l; I ++) {imgList. push (nodes [I]) ;};}) ();