在一个网站含有大量的图片,我们在进入一个页面的时候如果一下子全部加载完毕,就会造成很大的资源浪费,而懒加载就是用户浏览到哪里,就加载哪里的图片,这样就可以减少资源的浪费了。
1.懒加载的实现原理
一个img标签如果没有src属性,浏览器就不会发起请求,所以我们在图片没有进入可视区域之前就不会给img标签赋值src属性
2.懒加载的实现方式
window.innerHeight:浏览器可视区域高度
document.body.scrollTop || document.documentElement.scrollTop:浏览器滚动条滚过高度(考虑到了兼容)
img.offsetTop:元素距文档顶部的高度

图片的加载条件:img.offsetTop < window.innerHeight + document.body.scrollTop;
基础代码:
1 2 3 4 5 6 7 8 9 10 11 12
| <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>
|
但是我们需要优化一下基础代码,为了防止重复加载,我们需要对基础代码中的函数使用函数节流
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| <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>
|
(2)使用IntersectionObserver方法
基本知识
1 2 3 4 5 6 7
| var io = new IntersectionObserver(callback, option);
io.observe(document.getElementById('example'));
io.unobserve(element);
io.disconnect();
|
callback是可见性变化时的回调函数,option是配置对象。这个构造函数的返回值是一个观察器实例。构造函数的返回值是一个观察器实例,实例的observe方法可以指定观察哪个DOM节点。
上面代码中,observe的参数是一个DOM节点对象。如果要观察多个节点,就要多次调用这个方法。callback函数的参数(entries)是一个数组,每个成员都是一个IntersectionObserverEntry对象。举例来说,如果同时有两个被观察的对象的可见性发生变化,entries数组就会有两个成员。intersectionRatio:目标元素的可见比例,完全可见时为1,完全不可见时小于等于0。
完整代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| <script type="text/javascript"> var observer = new IntersectionObserver(function(changes){ console.log(changes); changes.forEach(function(index,item){ if(item.intersectionRatio > 0 && item.intersectionRatio < 1) item.target.src = item.target.dataset.src; }); }); function addObserver(){ var listItems = document.querySelectorAll('.img-item'); listItems.forEach(function(item){ observer.observe(item); }); } addObserver(); </script>
|