一、使用loading="lazy"
<img src="./area_520602.jpg" loading="lazy">
直接在标签中使用loading="lazy"属性即可。
不过该属性有兼容性问题,具体可以在can i use中查看
二、js实现图片懒加载
js方式实现图片懒加载有多种方式,常见的主要是offsetTop和getBoundingClientRect视窗方式,本篇主要实现getBoundingClientRect方式。
getBoundingClientRect()
该方法用于获取元素到浏览器视窗的距离,得到的参数如下:
- rect.top 元素上边到视窗上边的距离
- rect.right 元素右边到视窗左边的距离
- rect.bottom 元素下边到视窗上边的距离
- rect.left 元素左边到视窗左边的距离
- rect.x 元素左上角到视窗左边的距离
- rect.y 元素左上角到视窗上边的距离
- rect.width 是元素自身的宽
- rect.height 是元素自身的高
实现lazyload
function lazyload() {
const viewHeight = window.innerHeight || document.documentElement.clientHeight || document.body.clientHeight
const imgs = document.querySelectorAll('img[data-src]')
imgs.forEach((img, index) => {
// 如该图片没有data-src属性,return
if (img.dataset.src === '') reutrn
const imgRect = img.getBoundingClientRect()
// 图片顶部到视窗顶部的距离小于视窗高度时,重新设置src属性
if(imgRect.bottom >= 0 && imgRect.top < viewHeight) {
// src重新赋值
img.src = img.dataset.src
// 删除data-src属性
img.removeAttribute('data.src')
}
})
}
添加scroll事件,实现懒加载功能
window.addEventListener('scroll', lazyload)
节流走一波,提高性能
// 节流函数
// 节流
function throttle(fn, delay) {
let flag = null
return function () {
if (flag) return
flag = setTimeout(() => {
fn.apply(this, arguments)
// 最后在setTimeout执行完毕后再把标记设置为null(关键)
// 表示可以执行下一次循环了。
flag = null
}, delay)
}
}
// scroll监听添加节流
window.addEventListener('scroll', throttle(lazyload, 200))
至此,我们getBoundingClientRect方式实现图片懒加载就完成了,是不是特别简单?
简单demo
<!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>
<style>
* {
margin: 0;
padding: 0;
}
.box {
width: 900px;
margin: 0 auto;
}
img {
width: 100%;
height: 400px;
}
</style>
</head>
<body>
<div class="box">
<img data-src="./area_520602.jpg" src="./default.png" alt="">
<img data-src="./area_520603.jpg" src="./default.png" alt="">
<img data-src="./area_520621.jpg" src="./default.png" alt="">
<img data-src="./area_520622.jpg" src="./default.png" alt="">
<img data-src="./area_520623.jpg" src="./default.png" alt="">
<img data-src="./area_520624.jpg" src="./default.png" alt="">
<img data-src="./area_520625.jpg" src="./default.png" alt="">
</div>
<script>
// 节流函数
function throttle(callback, delay) {
var timeout
return function() {
let content = this
let args = arguments
if(!timeout) {
timeout = setTimeout(function(){
timeout = null
callback.apply(content, args)
},delay)
}
}
}
function lazyload() {
console.log('lozyload')
const viewHeight = window.innerHeight || document.documentElement.clientHeight || document.body.clientHeight
const imgs = document.querySelectorAll('img[data-src]')
imgs.forEach((img, index) => {
// 如该图片没有data-src属性,return
if (img.dataset.src === '') reutrn
const imgRect = img.getBoundingClientRect()
// 图片距离视窗顶部的距离小于视窗高度时,重新设置src属性
if(imgRect.bottom >= 0 && imgRect.top < viewHeight) {
// src重新赋值
img.src = img.dataset.src
// 删除data-src属性
img.removeAttribute('data.src')
}
})
}
lazyload()
window.addEventListener('scroll', throttle(lazyload, 200))
</script>
</body>
</html>