图片懒加载个人总结

91 阅读1分钟

最近在过面试题发现图片懒加载也有人问,正常开发就是在图片加上loading=“lazy”咯,但是底层原理你知道吗,我这里总结一下

传统js+节流

这种方法比较好理解,但是要加一个节流,不然会多次触发,一打开页面马上就全部加载了,不贴合实际的开发场景。所以加个节流会好点。根本思路就是滚动条的高度(不同浏览器适配不同)document.body.scrollTop||document.documentElement.scrollTop||window.pageYOffset,加上页面可视的高度window.innerHeight大于图片距离顶部高度img.offsetTop。
代码: ` function throttle(fn, delay) { let timer = null return function (...args) { if (!timer) { timer = setTimeout(() => { timer = null fn.apply(this, args) }, delay) } } } const imglist = document.querySelectorAll("img") console.log(imglist)

    window.addEventListener("scroll", throttle(lazyload, 500));

    function lazyload() {
        let seeheight = window.innerHeight;
        let scrollnum = document.documentElement.scrollTop || document.body.scrollTop;
        for (let ig of imglist) {
            if (ig.offsetTop < seeheight + scrollnum) {
                console.log("触发了")
                let trueSrc = ig.getAttribute("data-src")
                ig.setAttribute("src", trueSrc)
            }
        }

    }`

IntersectionObserver

​IntersectionObserver API,可以自动"观察"元素是否可见,由于可见(visible)的本质是,目标元素与视口产生一个交叉区,所以这个 API 叫做"交叉观察器"。

IntersectionObserverEntry 对象

  • time:可见性发生变化的时间,是一个高精度时间戳,单位为毫秒

  • target:被观察的目标元素,是一个 DOM 节点对象

  • rootBounds:根元素的矩形区域的信息,getBoundingClientRect()方法的返回值,如果没有根元素(即直接相对于视口滚动),则返回null

  • boundingClientRect:目标元素的矩形区域的信息

  • intersectionRect:目标元素与视口(或根元素)的交叉区域的信息

  • intersectionRatio:目标元素的可见比例,即intersectionRect占boundingClientRect的比例,完全可见时为1,完全不可见时小于等于0 `

      const observer=new IntersectionObserver(callback=>{
          callback.forEach(item=>{
              if(item.isIntersecting){
              const image=item.target;
              const trueimg=image.getAttribute('data-src')
              image.setAttribute('src',trueimg)
    
              // 加载完后不用观察了
              observer.unobserve(image)
    
              }
          })
      })
      imaglist.forEach(item=>{
          observer.observe(item)
      })
    
    
      
    

    `