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>

上一篇下一篇

猜你喜欢

热点阅读