现在的科技发达,图片的资源占比越来越大,对图片在页面的优化已经成为前端开发必备的技术之一,难的图片懒加载方法咱们看着头大,简单,易懂的才适合我们程序员。
很好,开始第一步将图片的标签放好,设定一个data-origin
标签在img当中,这样使用data-
的命名方式是为了与HTML5的自定义数据属性约定保持一致。
简单的方式
思路就是
- 先获取到可视区域,我们使用
clientHeight
,它可以获取到html元素的客户端高度。 - 获取到带有
data-origin
标签的全部img属性 - 获取每张图片相对视窗口的高度,使用
getBoundingClientRect
,其中包含各种元素相对于视口的信息和元素本身的信息。 - 一旦图片相对于视窗顶部的距离小于可视区域高度,那就将
data-origin
标签的url赋给src,最后清除data-origin
标签。
html
<style>
img{
height: 300px;
width: 300px;
margin-bottom: 50px;
display: block;
}
</style>
</head>
<body>
<img src="" data-origin="https://t7.baidu.com/it/u=2604797219,1573897854&fm=193&f=GIF" alt="">
<img src="" data-origin="https://img1.baidu.com/it/u=435134468,1942448903&fm=253&fmt=auto&app=120&f=JPEG?w=500&h=889" alt="">
<img src="" data-origin="https://img0.baidu.com/it/u=3628503530,464378779&fm=253&fmt=auto&app=120&f=JPEG?w=1200&h=800">
<img src="" data-origin="https://img2.baidu.com/it/u=855369075,175194576&fm=253&fmt=auto&app=138&f=JPEG?w=800&h=500" alt="">
<img src="" data-origin="https://img2.baidu.com/it/u=2004708195,3393283717&fm=253&fmt=auto&app=138&f=JPEG?w=750&h=500" alt="">
<img src="" data-origin="https://img1.baidu.com/it/u=1331863463,2594844301&fm=253&fmt=auto?w=1067&h=800" alt="">
<img src="" data-origin="https://img1.baidu.com/it/u=1331863463,2594844301&fm=253&fmt=auto?w=1067&h=800" alt="">
<img src="" data-origin="https://img0.baidu.com/it/u=2788901948,3907873318&fm=253&fmt=auto?w=500&h=281" alt="">
<img src="" data-origin="https://img2.baidu.com/it/u=811993169,635123395&fm=253&fmt=auto&app=138&f=JPEG?w=500&h=889" alt="">
<img src="" data-origin="https://img0.baidu.com/it/u=924031950,2251460669&fm=253&fmt=auto&app=138&f=JPEG?w=1105&h=500" alt="">
<script>
//获取可视区域的高度 offsetHeight包含外部高度(边框)
const viewHeight = document.documentElement.clientHeight //window.innerHeight
// console.log(viewHeight);
function lazyLoad(){
const imgs = document.querySelectorAll('img[data-origin]') //属性选择
console.log(imgs);
imgs.forEach(item =>{
let res = item.getBoundingClientRect()
// console.log(res);
if(res.top < viewHeight){
item.src = item.dataset.origin
item.removeAttribute('data-origin')
}
})
// 获取可视区域的高度
// const viewHeight = document.documentElement.clientHeight
// const io = new IntersectionObserver(
// (entries) => {
// entries.forEach(entry => {
// if (entry.isIntersecting) {
// entry.target.src = entry.target.dataset.original || ''
// entry.target.removeAttribute('data-original')
// io.unobserve(entry.target)
// }
// })
// },
// {
// threshold: 0
// }
// )
// const imgs = document.querySelectorAll('img[data-original]')
// imgs.forEach(item => {
// io.observe(item)
// })
}
document.addEventListener('scroll',lazyLoad)
lazyLoad()
</script>
</body>
第二个方法
第二个方法就相对更复杂一些,通过判断某个元素和父元素交叉比例来判断是否需要懒加载。是异步监听的。当交叉比例达到某个值就会触发回调函数。我们这里使用的是IntersectionObserver
方法,用一个外部box包裹所有图片,让图片超出box就滚动。看了上面的方法,这个方法也就明白在干什么了。
html
#box{
width: 100vw;
height: 100vh;
overflow: scroll;
}
img{
height: 300px;
margin-bottom: 50px;
display: block;
}
const viewHeight = document.documentElement.clientHeight
const io = new IntersectionObserver(
(entries) => {
entries.forEach(entry => {
//判断是否进入可视区
if (entry.isIntersecting) {
entry.target.src = entry.target.dataset.original || ''
//移除标签
entry.target.removeAttribute('data-original')
io.unobserve(entry.target)
}
})
},
{
取值范围从0~1,表示交叉比例
threshold: 0
}
)
//监听每一张图片
const imgs = document.querySelectorAll('img[data-original]')
imgs.forEach(item => {
io.observe(item)
})