dev-zuo 技术日常
Github

图片占位、懒加载、预览

这篇文章发布于 2020/11/23,归类于
标签:
怎么实现图片懒加载图片占位好处图片预览image lazyload图片懒加载

使用占位图片有什么好处?

  1. 用户体验更好,标识此处有图片,但正在加载中的这一个状态,避免弱网或图片较大时,完全不显示的问题
  2. 不阻塞其他资源加载,更快的整体文档加载速度,不阻塞其他请求。占位图片一般会和图片懒加载一起使用,当滚动到该区域时再加载图片,减少不必要的并发网络请求
  3. 可以避免回流/重排,让图片加载完成后不改变页面的整体布局,避免回流(重新布局),只需要重绘,注意: 需要占位图片与实际图片宽高不变

怎么实现图片懒加载

这里核心问题是怎么判断图片是否已滚动到当前视口。一般可以通过监听页面滚动事件,实时比较元素的 offsetTop 与页面的 scrollTop。另外还可以通过元素的 getBoundingClientRect() 获取当前元素距离视窗的距离,如果小于 window.innerHeight 就加载,下面来看一个简单的实现

<body>
  <div>
    <div style="height:50px;">我是占位文本</div>
    <img class="lazy-img" data-src="http://zuo11.com/images/blog/c/c_vim.png">
    <div style="height:500px;">我是占位文本</div>
    <img class="lazy-img" data-src="http://zuo11.com/images/blog/c/c_saolei_3.png">
  </div>
  <script>
    let imgEls = document.querySelectorAll('.lazy-img')
    let imgs = []
    imgEls.forEach(imgEl => {
      imgEl.style.height = '300px'
      imgEl.style.width = '300px'
      imgEl.src = "placeholder.png"
      // 存储信息用于监听滚动后比对
      imgs.push({
        offsetTop: imgEl.offsetTop,
        el: imgEl,
        src: imgEl.dataset.src,
        isLoad: false
      })
    })
    console.log(imgs)
    // 判断滚动位置,显示图片
    function showImg() {
      console.log('>>>>>>')
      imgs.forEach(item => {
        // 如果图片未加载
        if (!item.isLoad) {
          console.log(window.innerHeight, item.src, item.el.getBoundingClientRect())
          let elPos = item.el.getBoundingClientRect()
          if (elPos.top < window.innerHeight) {
            // 如果元素相对顶部的距离 < 视窗高度,加载图片
            item.el.src = item.src
            item.isLoad = true
          }
        }
      })
    }
    showImg()
    window.onscroll = () => {
      showImg()
    }
  </script>
</body>

图片预览

可以参考Element UI el-image组件实现,Element UI 大图预览 | el-image

参考资料与扩展