In a website containing a large number of pictures, when we enter a page, if all of a sudden loaded, it will cause a great waste of resources, and lazy loading is where users browse, where the load of pictures, so as to reduce the waste of resources.


1. The implementation principle of lazy loading

An IMG tag without a SRC attribute will not be requested by the browser, so we will not assign the SRC attribute to the img tag until the image is in the viewable area

2. Lazy loading implementation

(1) using the scrollTop/innerHeight/offsetTop

Window. innerHeight: The height of the browser’s viewable area

Document. The body. The scrollTop | | document. The documentElement. ScrollTop: browser scroll rolled highly compatible (considered)

img.offsetTop: Height of the element from the top of the document

Img. offsetTop < window.innerheight + document.body.scrollTop;

Basic code:

<script type="text/javascript"> var imgs = document.querySelectorAll('img'); window.onscroll = function(){ var scrollTop = document.body.scrollTop || document.documentElement.scrollTop; var winTop = window.innerHeight; for(var i=0; i < imgs.length; i++){ if(imgs[i].offsetTop < scrollTop + winTop ){ imgs[i].src = imgs[i].getAttribute('data-src'); } } } </script>Copy the code

But we need to optimize the underlying code. To prevent reloading, we need to use function throttling on the functions in the underlying code

<script type="text/javascript"> var imgs = document.querySelectorAll('img'); var lazyload = function(){ var scrollTop = document.body.scrollTop || document.documentElement.scrollTop; var winTop = window.innerHeight; for(var i=0; i < imgs.length; i++){ if(imgs[i].offsetTop < scrollTop + winTop ){ imgs[i].src = imgs[i].getAttribute('data-src'); } } } function throttle(method,delay){ var timer = null; return function(){ var context = this, args=arguments; clearTimeout(timer); timer=setTimeout(function(){ method.apply(context,args); },delay); } } window.onscroll = throttle(lazyload,200); </script>Copy the code

(2) IntersectionObserver method is adopted

Basic knowledge of

var io = new IntersectionObserver(callback, option); // observe IO. Observe (document.getelementbyid ('example')); // Stop observing IO. Serve (element); // Close the observer io.disconnect();Copy the code

Callback is the callback function when visibility changes, and option is the configuration object. The return value of this constructor is an observer instance. The return value of the constructor is an observer instance whose Observe method specifies which DOM node to observe.

In the code above, the argument to Observe is a DOM node object. Call this method multiple times if you want to observe multiple nodes. The parameters of the callback function (entries) is an array, each member is a IntersectionObserverEntry object. For example, if the visibility of two observed objects changes at the same time, the Entries array will have two members. IntersectionRatio: intersectionRatio of target elements is 1 when they are completely visible and less than or equal to 0 when they are completely invisible.

The complete code

<script type="text/javascript"> var observer = new IntersectionObserver(function(changes){ console.log(changes); ForEach (function(index,item){if(item.intersectionRatio > 0 && item.intersectionRatio < 1) //target: The observed target element is a DOM node object item.target. SRC = item.target.dataset. SRC; }); }); function addObserver(){ var listItems = document.querySelectorAll('.img-item'); Listitems. forEach(function(item){// Start observing observe.observe (item); // Start observing observe.observe (item); }); } addObserver(); </script>Copy the code