手写JS-图片懒加载

2,848 阅读2分钟

前言

在学习图片懒加载之前,我们先看看什么是懒加载。

1.什么是懒加载?

懒加载突出一个“懒”字,懒就是拖延迟的意思,所以“懒加载”说白了就是延迟加载,比如我们加载一个页面,这个页面很长很长,长到我们的浏览器可视区域装不下,那么懒加载就是优先加载可视区域的内容,其他部分等进入了可视区域再加载。

2.为什么要懒加载?

懒加载是一种网页性能优化的方式,它能极大的提升用户体验。就比如说图片,图片一直是影响网页性能的主要元凶,现在一张图片超过几兆已经是很经常的事了。但是如果每次进入页面就请求所有的图片资源,那么加载时间会很长,可能等图片加载出来用户也早就走了。所以,我们需要懒加载,如果进入页面,那么只请求可视区域的图片资源。

总而言之,全部加载的话会影响用户体验,而且浪费用户的流量,有些用户并不会全部看完所有的图片,但是全部加载又会耗费大量流量,所以我们需要图片懒加载。

懒加载的实现原理

由于网页中占用资源较多的一般是图片,所以我们一般实施懒加载都是对图片资源而言的,所以这里的实现原理主要是针对图片。

大家都知道,一张图片就是一个标签,而图片的来源主要是src属性。浏览器是否发起亲求就是根据是否有src属性决定的。

既然这样,那么我们就要对标签的src属性下手了,在没进入可视区域的时候,我们先不给这个标签赋src属性,这样浏览器就不会发送请求了。

实现方式:了解一个API

图片懒加载的实现方式我们只需要了解一个API就行了:

getBoundingClientRect()//获取元素的大小及位置

懒加载的一个重点就是要知道什么时候图片是进入了可视区内,那么就上面这张图而言,我们有什么方法判断图片进入了可视区呢。

其实很简单:

我们先获取图片到可视区顶部的距离,并判断是否小于可视区的高度:

let rect=img.getBoundingClientRect()            
if(rect.top<window.innerHeight){

然后我们继续思考,当我们滚动条向下滚动的时候,rect.top值会变得越来越小,也就是图片到可视区顶部的距离也越来越小,所以当rect.top == innerHeight时,说明土片马上就要进入可视区了,只要我们在滚动,图片就会进入可视区,那么就需要请求资源了。也就是说,在rect.top<innertHeight时,图片是在可视区域内的。

经过上面的思考,我们大致明白了如何实现,那么就来手写我们的代码了吧!

let imgList=[...document.querySelectorAll('img')]
let length=imgList.lengthconst imgLazyLoad=function(){    
    let count=0    
    return (function () {        
        let deleteIndexList=[]        
        imgList.forEach((img,index)=>{            
            let rect=img.getBoundingClientRect()            
            if(rect.top<window.innerHeight){                
                img.src=img.dataset.src                
                deleteIndexList.push(index)                
                count++                
            if(count===length){                    
                document.removeEventListener('scroll',imgLazyLoad())                
            }            
          }        
        })        
     imgList=imgList.filter((img,index)=>!deleteIndexList.includes(index))    
    })()
}
document.addEventListener('scroll',imgLazyLoad)

与普通的图片懒加载不同,这段代码还做了 2 个处理:

  • 图片全部加载完成后移除事件监听;
  • 加载完的图片,从 imgList 移除;

总结:

图片懒加载其实就两个重点,一个是图片到各个边距的距离,二个就是判断图片是否在可视区域内。