图片懒加载

200 阅读1分钟

明白概念

页可见区域宽: document.body.clientWidth;
网页可见区域高: document.body.clientHeight;
网页可见区域宽: document.body.offsetWidth (包括元素的边框、内边距和滚动条);
网页可见区域高: document.body.offsetHeight (包括元素的边框、内边距和滚动条);
网页正文全文宽: document.body.scrollWidth;
网页正文全文高: document.body.scrollHeight;
网页被卷去的高: document.body.scrollTop;
网页被卷去的左: document.body.scrollLeft;
网页正文部分上: window.screenTop;
网页正文部分左: window.screenLeft;
屏幕分辨率的高: window.screen.height;
屏幕分辨率的宽: window.screen.width;
屏幕可用工作区高度: window.screen.availHeight;

offsetTop, offsetLeft:只读属性。要确定的这两个属性的值,首先得确定元素的offsetParent。
offsetParent指的是距该元素最近的position不为static的祖先元素,如果没有则指向body元素。
确定了offsetParent,offsetLeft指的是元素左侧偏移offsetParent的距离,同理offsetTop指的是上侧偏移的距离。

实现思路

  • 先拿到所有的img的个数
  • 最重要的一步:获取当前图片是否进入可视页面中
  • 若进入到可视页面将img的src属性赋值,使图片显示出来
  • 绑定windows.onload事件

如何判断进入可视区域呢? 若当前图片的offsetTop(相对于body顶部距离)小于document的clientHeight(网页可见区域的高)和document的scrollTop(卷上去的高度)的话则进入了可视区域

ok,废话不多说,上代码:

let count=0//用来计算加载到第几张图片
function lazyLoad(imgList){
  //获取当前body卷上去的高度(注意第二种获取方式用于没声明doctype)
  let scrollTop=document.body.scrollTop||document.documentElement.scrollTop;
  //获取页面可视区域高度
  let clientHeight=window.innerHeight;
 
  for(let i=count;i<imgList.length;i++){
    //下次从第count张图片开始循环,减少循环的个数
    if(imgList[i].offsetTop<scrollTop+clientHeight){
        imgList[i].src=imgList[i].getAttribute('data-src')
        count++
    }
  }
}
//因为scroll事件,所以会产生很多回流事件,
//因此给他加个节流,在1000ms内只触发一次事件
function throttle(fn,wait){
  let prev=0;
  //因为节流是对函数起到一个修饰性的作用,所以返回一个函数
  return function(){
    let args=[...arguments]
    let context=this;
    //注意在上下文获取当前时间,因为函数是在这里执行的
    let now=Date.now()
    if(wait<now-prev){
      console.log(11)
      fn.apply(context,args)
    prev=now;
  }
  }
}
//一进来页面需要首次加载一下图片,否则会白屏
lazyLoad(imgList);

window.onscroll=()=>{throttle(lazyLoad,1000)(imgList)}