第一种方法使用 getBoundingClientRect与视口关系,需要监听浏览器,使用防抖优化
第二种方法使用 IntersectionObserver函数
<!doctype html>
<html>
<head>
<title>图片懒加载</title>
<meta charset="utf-8" />
</head>
<body>
<div >
<img data-src="./w/1.png">
</div>
<div >
<img data-src="./w/2.jpeg">
</div>
<div >
<img data-src="./w/3.jpg">
</div>
<div >
<img data-src="./w/4.jpg">
</div>
<script>
function query(selector) {
return Array.from(document.querySelectorAll(selector))
}
#第一种方法使用 getBoundingClientRect与视口关系
document.addEventListener('DOMContentLoaded', function() {
const imgs = query('img')
function lazyLoad() {
const windowHeight = document.documentElement.clientHeight
imgs.forEach((img, i) => {
#通过 getBoundingClientRect() 获取到当前元素与视口的位置关系来确定图片是否加载,在加载完成之后为了性能考虑,删除 data-src
if (img.dataset.src && img.getBoundingClientRect().bottom >= 0 && windowHeight > img.getBoundingClientRect().top) {
img.src = img.dataset.src
delete img.dataset.src
}
})
}
lazyLoad()
document.addEventListener('scroll', debounce(lazyLoad, 200))
})
#防抖优化
function debounce(func, wait) {
let timer = null
return function(...args) {
if (timer) clearTimeout(timer)
timer = setTimeout(() => {
func(...args)
}, wait)
}
}
#第二种方法使用 IntersectionObserver函数
#const observer = new IntersectionObserver(entries => {
# entries.forEach((entry) => {
# const target = entry.target;
# const intersectionRatio = entry.intersectionRatio
# if (intersectionRatio > 0 && intersectionRatio <= 1) {
# if (target.dataset.src) {
# target.src = target.dataset.src
# delete target.dataset.src
# console.log(1)
# target.onload = target.onerror = () => {
# observer.unobserve(target)
# }
# }
# }
# })
# }
#)
#query('img').forEach(function (item) {
# observer.observe(item)
#})
</script>
</body>
<style>
div{
width: 500px;
height: 500px;
}
img{
width: 100%;
height: 100%;
}
</style>
</html>