实际项目开放中,特别是电商项目,由于有大量的图片加载必然会影响性能,所以实现图片的懒加载是非常有必要的。
实现图片懒加载的知识点
标签的data-属性 可视区域的监听
实现图片懒加载的原理
<img alt="loading..." data-src="images/1.jpg"> 当我们监听到图片进入可视区域后,就将data-src到值赋值给src属性 <script> var images = document.querySelectorAll(‘img‘); //ES6方法,也可以直接使用for语句 Array.from(images).forEach((el)=>{ el.src = el.dataset.src; }) </script>
Element.getBoundingClientRect()方法
rectObject = object.getBoundingClientRect();
返回值是一个 DOMRect 对象,这个对象是由该元素的 getClientRects()
方法返回的一组矩形的集合, 即:是与该元素相关的CSS 边框集合 。DOMRect 对象包含了一组用于描述边框的只读属性——left、top、right和bottom,单位为像素。除了 width 和 height 外的属性都是相对于视口的左上角位置而言的。
通过这个API,我们就很容易获取img元素相对于视口的顶点位置"rectObject.top",只要这个值小于浏览器的高度(window.innerHeight)就说明进入可视区域。如果要提前加载,可以添加将浏览器的高度加值。
function isInSight(el){ const bound = el.getBoundingClientRect(); const clientHeight = window.innerHeight; return bound.top <= clientHeight + 100; }
实现图片加载
function loadImg(el){ if(!el.src){ const source = el.dataset.src; el.src = source; } }
将判断进入可视区域的函数与加载图片的函数放入页面函数,在页面加载与滚动的时候调用函数
function checkImgs(){ const imgs = document.querySelectorAll(‘li img‘); Array.from(imgs).forEach(el =>{ if (isInSight(el)){ loadImg(el); } }) } window.onload = function(){ checkImgs(); } document.onscroll = function () { checkImgs(); }
到这里就完成了图片懒加载,但会存在一些性能问题,比如:加载过的图片不需要在遍历了、两次滚动时间间隔很短(抖动问题)。这些优化问题就不在这儿写了,以后有时间再补上去。接下来会写另一个ES6实现图片懒加载的API——“IntersectionObserver
”,这个API实现性能会更好。