实现图片懒加载

一、什么是懒加载?

“懒加载”即:延迟加载,对于一个很长的页面,优先加载可视区域的内容,其他部分等进入了可视区域在加载。

二、为什么要懒加载?

懒加载是一种网页性能优化的方式,它能极大的提升用户体验。比如一个页面中有很多图片,但是首屏只出现几张,这时如果一次性把图片全部加载出来会影响性能。这时可以使用懒加载,页面滚动到可视区再加载。优化首屏加载。

总结出来就两个点:

1.全部加载的话会影响用户体验

2.浪费用户的流量,有些用户并不想全部看完,全部加载会耗费大量流量。

懒加载优点:页面加载速度快,减轻服务器压力,节约流量,用户体验好。

三、懒加载的实现原理?

在没进入可视区域的时候,img 标签的 src 设置默认图片,data-src 自定义属性存放图片真实的地址,当页面滚动直至此图片出现在可视区域时,用 js 取到该图片的 data-src 的值赋给 src。

四、实现方案

首先给图片一个占位资源: 

方案一: clientHeight、scrollTop 和 offsetTop

实现图片懒加载_第1张图片

接着,通过监听 scroll 事件来判断图片是否到达视口:

let img = document.getElementsByTagName("img");
let num = img.length;
let count = 0;//计数器,从第一张图片开始计

lazyload();//首次加载别忘了显示图片

window.addEventListener('scroll', lazyload);

//offsetTop是元素与offsetParent的距离,循环获取直到页面顶部
function getTop(el) {
    var T = el.offsetTop;
    while(el = el.offsetParent) {
        T += el.offsetTop;
    }
    return T;
}

function lazyload() {
  let viewHeight = document.documentElement.clientHeight || document.body.clientHeight;//视口高度
  let scrollTop = document.documentElement.scrollTop || document.body.scrollTop;//滚动条卷去的高度
  for(let i = count; i 

offsetParent 就是距离该子元素最近的进行过定位的父元素(position:absolute  relative fixed),如果其父元素中不存在定位则offsetParent为:body元素

方案二:getBoundingClientRect

getBoundingClientRect 方法返回元素相对视口左上角的偏移量以及元素本身长宽,单位:px。

 

实现图片懒加载_第2张图片

上述的 lazyload 函数改成下面这样: 

function lazyload() {
    let viewHeight = document.documentElement.clientHeight || document.body.clientHeight;
    for(let i = count; i 

方案三: IntersectionObserver

有兼容性问题

这是浏览器内置的一个API,实现了监听window的scroll事件判断是否在视口中以及节流三大功能。

我们来具体试一把:

let img = document.getElementsByTagName("img");

const observer = new IntersectionObserver(changes => {
  //changes 是被观察的元素集合
  for(let i = 0, len = changes.length; i < len; i++) {
    let change = changes[i];
    // 通过这个属性判断是否在视口中
    if(change.isIntersecting) {
      const imgElement = change.target;
      imgElement.src = imgElement.getAttribute("data-src");
      observer.unobserve(imgElement);
    }
  }
})
Array.from(img).forEach(item => observer.observe(item));

这样就很方便地实现了图片懒加载,当然这个IntersectionObserver也可以用作其他资源的预加载,功能非常强大。


 

 

 

你可能感兴趣的:(JavaScript)