图片懒加载

date
Jul 21, 2019
slug
img-lazy-loading
status
Published
tags
前端
笔记
summary
图片”懒“加载其实就是延时加载,原理就是判断图片当前的位置是否在你看的区域里。
type
Post
📖
实现一个图片懒加载涉及到JavaScript的知识点:视口位置判断、防抖节流。

懒加载原理

图片能够被用户看到,是因为浏览器向服务器发出了请求,能够发出请求是根据<img>标签中src属性是否存在。
那么我们就让初始的<img>标签所有src属性都为空,判断当图片的位置进入到可视区域中的时候去给<img>标签赋值src属性,这样就实现懒加载了。

懒加载的实现

方法一

  1. 通过document.documentElement.clientHeight获取屏幕可视窗口高度
  1. 通过element.offsetTop获取元素相对于文档顶部的距离
  1. 通过document.documentElement.scrollTop获取浏览器窗口顶部与文档顶部之间的距离,也就是滚动条滚动的距离
公式:元素距离文档顶部的距离-滚动条滚动的具体<屏幕可视窗口高度 = 2-1<3
缺点:只适用于下拉的时候去判断,如果当前在页面最底部,用户跳转到其他页面,返回过来还在最底部的话,就会加载所有的图片了
实现:

方法二

利用getBoundingClientRect()方法来获取元素的大小以及位置,这个方法返回一个名为ClientRectDOMRect对象,包含了toprightbottonleftwidthheight这些值。
也就是说rect.top = viewHeight时,说明元素的顶部刚好在可视窗口的底部,那么rect.top < viewHeight时,元素就肯定在可视窗口内了。
公式:rect.top < viewHeight
问题来了:在方法一种如果页面在底部,我们去刷新就会一直加载全部的图片。就要确保这个元素确确实实要在我们的可视窗口内,从上图中可以看到,再加一个判断,rect.bottom>=0
升级我们的公式:
公式:rect.top < viewHeight && rect.bottom >= 0
实现:

方法三

IntersectionObserver可以自动观察元素是否在视口内。
callback的参数是一个数组,每个数组都是一个IntersectionObserverEntry对象,包括以下属性:
属性
描述
time
可见性发生变化的时间,单位为毫秒
rootBounds
与getBoundingClientRect()方法的返回值一样
boundingClientRect
目标元素的矩形区域的信息
intersectionRect
目标元素与视口(或根元素)的交叉区域的信息
intersectionRatio
目标元素的可见比例,即intersectionRect占boundingClientRect的比例,完全可见时为1,完全不可见时小于等于0
target
被观察的目标元素,是一个 DOM 节点对象
我们需要用到intersectionRatio来判断是否在可视区域内,当intersectionRatio > 0 && intersectionRatio <= 1即在可视区域内。
公式:intersectionRatio > 0 && intersectionRatio <= 1

参考链接

 

© Ayden 2021 - 2024