IntersectionObserver对象使用实现懒加载
2020-11-24 本文已影响0人
Raral
懒加载原理
传统的实现方法是,监听到scroll
事件后,调用目标元素(绿色方块)的getBoundingClientRect()
方法,得到它对应于视口左上角的坐标,再判断是否在视口之内。这种方法的缺点是,由于scroll
事件密集发生,计算量很大,容易造成性能问题。
目前有一个新的 IntersectionObserver API(https://wicg.github.io/IntersectionObserver/),可以自动"观察"元素是否可见,Chrome 51+ 已经支持。由于可见(visible)的本质是,目标元素与视口产生一个交叉区,所以这个 API 叫做"交叉观察器"。
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<style type="text/css">
html,body {
margin: 0;
padding: 0;
}
h1 {
text-align: center;
}
.scroll-con {
height: 500px;
overflow-y: auto;
overflow-x: hidden;
background-color: antiquewhite;
}
.scroll-con-img {
height: 400px;
width: 80%;
opacity: 0;
transform: translateX(50%);
transition: all 1s;
}
.fade {
transform: translateX(0);
opacity: 1;
transition: all 1s;
}
</style>
</head>
<body>
<div class="scroll-con">
<h1>fsdf</h1>
<h1>fsdf</h1>
<h1>fsdf</h1>
<h1>fsdf</h1>
<h1>fsdf</h1>
<h1>fsdf</h1>
<h1>fsdf</h1>
<h1>fsdf</h1>
<img class="scroll-con-img" data-src="xxx" >
<img class="scroll-con-img" data-src="xxx" >
<img class="scroll-con-img" data-src="xxx" >
<img class="scroll-con-img" data-src="xxx" >
</div>
</body>
<script type="text/javascript">
const con = document.querySelector(".scroll-con")
const imgs = document.querySelectorAll(".scroll-con-img")
// con.addEventListener("scroll", () => {
// imgs.forEach(img => {
// const imgTop = img.getBoundingClientRect().top;
// const conTop = con.getBoundingClientRect().top;
// if(imgTop - conTop <= con.clientHeight) {
// const src = img.getAttribute("data-src");
// img.setAttribute("src", src);
// img.classList.add("fade");
// }
// })
// })
// 新的api dom边界处理
console.log(IntersectionObserver)
const options = {
root: con,
threshold:1,//交会处
rootMargin:"0px"//对视口进行收缩和扩张
}
function lazyLoad(target) {
const io = new IntersectionObserver((entries,observer) => {
entries.forEach(entry => {
if(entry.isIntersecting) {
const img = entry.target
const src = img.getAttribute("data-src")
img.setAttribute("src", src)
img.classList.add("fade")
observer.disconnect()
}
})
}, options)
io.observe(target)
}
imgs.forEach(img => {
lazyLoad(img)
});
</script>
</html>