1.懒加载概念
对于页面有很多静态资源的情况下(比如网商购物页面),为了节省用户流量和提高页面性能,可以在用户浏览到当前资源(当前窗口(可视区域)的大小)的时候,再对资源进行请求和加载。
懒加载实现原理
我们的图片要显示出来的话一般是借用img标签,然后把src属性写上图片的地址,才能把图片显示出来,那就想,我们先把图片不显示出来,就来写一个自定义属性字段,把这个属性字段的值写成图片地址,当图片在可视区域的范围的时候,就把自定义属性的值作为src的值。这就实现了懒加载。
<img src="" lazyload="true" data-original="https://t7.baidu.com/it/u=1732966997,2981886582&fm=193&f=GIF" alt=""
class="image-item">
data-original是我们自己定义的属性字段,它的值为我们要的图片地址。lazyload="true"是为了当图片加载出来后将图片不在需要懒加载了。(也可以不需要)
可视区域怎么找呢?
使用:document.documentElement.clientHeight可以获取到当前屏幕的高度。
当我们获取到高度之后,在想,如果这个图片在这个区域内,就让图片显示出来。
然后在想:当页面发生上滑的时候,可视区域的图片就会发生改变,所以当鼠标滚轮滚动的时候,在可视区域的图片就可能出去可视区域了,不在的可能这时候就进来了可视区域。所以我们要写一个监听事件。
//获取可视区域的高度
var viewHeight = document.documentElement.clientHeight
//鼠标滚动的时候就要监听事件并且有一个函数去执行
document.addEventListener('scroll', function () {
//获取到页面上所有的img
//判断某个是否进入可视区域
//如果进入,就把它自身的data-original的值取出来放到src
var arr = document.querySelectorAll('img[data-original][lazyload]')
//这行代码的意思是获取所有的图片(具备data-original和lazyload的这两个属性的图片)
当我们拿到所有的img时,利用循环去判断他们是否在可视区域内,在就加载出来,不在就暂时不加载。 所以需要满足的条件是图片的顶部在可视区域的高度里面,图片的底部也要在可视区域里面,也就是图片没有被划出去。
arr.forEach(item => {
let rect = item.getBoundingClientRect()//用于一次性获取某个容器相对于浏览器上下左右的位置
if (rect.top < viewHeight && rect.bottom >= 0) {
item.src = item.dataset.original
item.removeAttribute('data-original')
item.removeAttribute('lazyload')
}
})
完整代码:
<!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>
<style>
.image-item {
height: 300px;
display: block;
margin-bottom: 50px;
}
</style>
<body>
<img src="" lazyload="true" data-original="https://t7.baidu.com/it/u=1732966997,2981886582&fm=193&f=GIF" alt=""
class="image-item">
<img src="" lazyload="true" data-original="https://t7.baidu.com/it/u=1785207335,3397162108&fm=193&f=GIF" alt=""
class="image-item">
<img src="" lazyload="true" data-original="https://t7.baidu.com/it/u=2581522032,2615939966&fm=193&f=GIF" alt=""
class="image-item">
<img src="" lazyload="true" data-original="https://t7.baidu.com/it/u=3423293041,3900166648&fm=193&f=GIF" alt=""
class="image-item">
<img src="" lazyload="true" data-original="https://t7.baidu.com/it/u=1417505637,1247476664&fm=193&f=GIF" alt=""
class="image-item">
<img src="" lazyload="true" data-original="https://t7.baidu.com/it/u=3659156856,3928250034&fm=193&f=GIF" alt=""
class="image-item">
<img src="" lazyload="true" data-original="https://t7.baidu.com/it/u=1416385889,2308474651&fm=193&f=GIF" alt=""
class="image-item">
<img src="" lazyload="true" data-original="https://t7.baidu.com/it/u=1599162854,1822154160&fm=193&f=GIF" alt=""
class="image-item">
<img src="" lazyload="true" data-original="https://t7.baidu.com/it/u=1476844859,894832600&fm=193&f=GIF" alt=""
class="image-item">
<img src="" lazyload="true" data-original="https://t7.baidu.com/it/u=3728410568,989468460&fm=193&f=GIF" alt=""
class="image-item">
<img src="" lazyload="true" data-original="https://t7.baidu.com/it/u=3696285528,2808863331&fm=193&f=GIF" alt=""
class="image-item">
</body>
<script>
//获取可视区域的高度
var viewHeight = document.documentElement.clientHeight
document.addEventListener('scroll', function () {
//获取到页面上所有的img
//判断某个是否进入可视区域
//如果进入,就把它自身的data-original的值取出来放到src
var arr = document.querySelectorAll('img[data-original][lazyload]')
// console.log(arr);
/* for(var i of arr){
if(arr[i].offsettop()<i){
}
} */
arr.forEach(item => {
let rect = item.getBoundingClientRect()//用于一次性获取某个容器相对于浏览器上下左右的位置
if (rect.top < viewHeight && rect.bottom >= 0) {
item.src = item.dataset.original
item.removeAttribute('data-original')
item.removeAttribute('lazyload')
}
})
})
</script>
</html>
总结:懂得理论就很容易把代码写出来。