1200字范文,内容丰富有趣,写作的好帮手!
1200字范文 > 两种方法实现图片懒加载

两种方法实现图片懒加载

时间:2021-01-16 14:09:31

相关推荐

两种方法实现图片懒加载

懒加载的实现原理

图片的加载是由src引起的,当src赋值时,浏览器就会请求图片资源。根据这个原理,我们使用HTML5 的data-xxx属性来储存图片的路径,在需要加载图片的时候,将data-xxx中图片的路径赋值给src,这样就实现了图片的按需加载,即懒加载。

1.通过getBoundingClientRect()和window.innerHeight

流程:

获得图片列表imgList = [...document.querySelectorAll('img')]创建懒加载自执行函数,创建空数组,把加载过的图片下标加入数组监听滚动事件遍历图片,获得图片相对于视口的位置。getBoundingClientRect().top图片位置小于window.innerHeight,则更改src,getAttribute(‘’)设置透明度当加载完所有图片,移除监听事件document.removeEventListener('scroll', imgLazyLoad)

<!DOCTYPE html><html lang="en"><head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title></head><body><style>.box{background-color: #DDD;width:200px;height:100px;}.box img{opacity: 0;transition: opacity 2s;}</style><div class="box"><img src='' data-src="./1.jpg"/ style="width:200px; height:100px;"></div><br><br><br><br><br><br><br><div class="box"><img src='' data-src="./1.jpg"/ style="width:200px; height:100px;"></div><br><br><br><br><br><br><br><div class="box"><img src='' data-src="./1.jpg"/ style="width:200px; height:100px;"></div><br><br><br><br><br><br><br><div class="box"><img src='' data-src="./1.jpg"/ style="width:200px; height:100px;"></div><br><br><br><br><br><br><br><div class="box"><img src='' data-src="./1.jpg"/ style="width:200px; height:100px;"></div><br><br><br><br><br><br><br><script type="text/javascript">let imgList = [...document.querySelectorAll('img')]let length = imgList.lengthconst imgLazyLoad = (function() {let count = 0return function() {let deleteIndexList = []//遍历图片imgList.forEach((img, index) => {let rect = img.getBoundingClientRect()//出现在可视窗口时,开始加载if (rect.top < window.innerHeight) {//更改地址img.src=img.getAttribute('data-src')//设置透明度img.onload=()=>{img.style.opacity=1} deleteIndexList.push(index)count++//加载完所有图片之后,移除滚动条的监听事件if (count === length) {document.removeEventListener('scroll', imgLazyLoad)}}})//加载过的图片从列表中移除imgList = imgList.filter((img, index) => !deleteIndexList.includes(index))}})()//监听滚动事件document.addEventListener('scroll', imgLazyLoad)</script></body></html>

2,通过IntersectionObserver接口(交叉观察器)

创建观察器:newIntersectionObserver(callback,option);

callback一般会触发两次。一次是目标元素刚刚进入视口(开始可见),另一次是完全离开视口(开始不可见)。

callback函数的参数(entries)是一个数组,被观察的对象。

用到的两个api:

IntersectionObserverEntry.target (en-US)只读,获得可视区域内的元素

IntersectionObserverEntry.isIntersecting(en-US)只读,返回一个布尔值, 如果目标元素与交叉区域观察者对象的根相交,则返回true.(是否在可视区域内)

添加观察:observer()

取消观察:unobserver()

流程:

获取所有图片创建监听器,并指定回调函数IntersectionObserver(dd)给每个img都添加监视 observe.observe(img)遍历回调函数中的参数(数组:被观察的对象),判断其是否在可视区域内isIntersecting,如果在,则获取该元素target更改src,改变透明度,取消观察observe.unobserve(img)

<!DOCTYPE html><html lang="en"><head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0"><meta name="viewport" content="width=device-width, initial-scale=0.5, minimum-scale=0.5, maximum-scale=0.5"/><title>Document</title><style>img{opacity: 0;transition: opacity 2s;}</style></head><body><img src="" data-src="1.jpg" style="width:200px;height:200px;"><br/><br/><br/><br/><br/><img src="" data-src="1.jpg" style="width:200px;height:200px;"><br/><br/><br/><br/><br/><img src="" data-src="1.jpg" style="width:200px;height:200px;"><br/><br/><br/><br/><br/><img src="" data-src="1.jpg" style="width:200px;height:200px;"><br/><br/><br/><br/><br/><img src="" data-src="1.jpg" style="width:200px;height:200px;"><br/><br/><br/><br/><br/><img src="" data-src="1.jpg" style="width:200px;height:200px;"><br/><br/><br/><br/><br/><img src="" data-src="1.jpg" style="width:200px;height:200px;"><br/><br/><br/><br/><br/><script type="text/javascript">let list=document.querySelectorAll('img')const dd=arr=>{arr.forEach(item=>{if(item.isIntersecting){let img=item.targetimg.src=img.getAttribute('data-src')img.onload=()=>{img.style.opacity=1}observer.unobserve(img)}})}let observer=new IntersectionObserver(dd)list.forEach(img=>{observer.observe(img)})</script></body></html>

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。