我是大学生,我写一篇图片懒加载,你们看看行不行

36 阅读3分钟

懒加载,

pa ca(啪擦),打开页面,全是图,加载也加载不出来,网也卡,电脑性能也不行,

拜拜了您嘞,这一生都不会打开这个网站了。


是不是,流失了粉丝,错失了mOney,可惜可恨可悲。


我是前端,那我怎么来救一救。

所以像这种图片很多的网站,一定要做懒加载。


当我们的页面并未滚动到的时候,先占位吧:

<div
  data-v-b123=""
  data-vb345=""
  data-src="xxx我是图片链接"
  class="lazy thumb"
  style="background-image: none; background-size: cover;"
>
</div>

background-image: none; none 掉,就是一个占位的作用。

滚动到可见范围,然后div元素的内容才变化:

style 在可视范围才变化:

style="background-image: url(&quot;xxx各位我是图片链接xxx&quot;); background-size: cover"

可以看得出来吧,none变成了图片素材地址。


思路

各位,思路来啦:

在可视区域,div 立刻 把 style里面的background-image变换掉。这就是我这篇文章的主旨思想。

这就是原理,这就是底层思想逻辑。


写吧

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>Lazy-Load</title>
  <style>
    .img {
      width: 200px;
      height; 200px;
    }
  </style>

  <body>
    <div class="container">
      <div class="img">
        // 只是写了data-src,还没写src哦,注意
        <img class="pic" alt="加载中" data-src="./images/1.png">
      </div>
      // ... 这里很多很多这种img的div里面包着img
    </div>
  </body>
</head>
</html>

关键点: 可视区域高度、元素距离可视区域顶部高度

可视区域高度

可视区域高度:window.innerHeight获取。

兼容写法是这样的: const viewHeight = window.innerHeight || document.documentElment.clientHeight

元素距离可视区域 顶部高度

getBoundingClientRect()获取返回元素的大小,以及 相对视口的位置。一个是元素大小,一个是相对视口位置。

<script>
  // 获取所有图片元素
  const imgs = document.getElementsByTagName('img')
  
  // 可视区域的高度
  const viewHeight = window.innerHeight || document.docoumentElement.clientHeight

  // num 标识 到哪了 
  let num = 0

  function lazyload() {
  	for(let i = num; i < imgs.length; i++) {
  	  
  	  // 距离 = 可视化高度 - 元素距离顶部高度
  	  let distance = viewHeight - imgs[i].getBoundingClientRect().top

  	  // 元素出来了 
  	  if (distance >= 0) {

  	    // 把 data-src 搞到 src 上面去
  	  	imgs[i].src = imgs[i].getAttribute('data-src')

  	  	num = i + 1
  	  }

  	}
  }

  window.addEventListener('scroll', lazyload, false)
</scirpt>

这么写。


1. 涉及到的两个量

  • viewHeight 👉 浏览器窗口(可视区域)的高度。 比如你电脑屏幕显示网页的部分,不算浏览器顶部工具栏。

  • imgs[i].getBoundingClientRect().top 👉 当前图片距离可视区域顶部的距离。

    • 如果图片在屏幕上方(已经滚过),这个值可能是负数。
    • 如果图片还没到可视区域,这个值是大于 viewHeight 的。

2. 公式含义

distance = viewHeight - imgs[i].getBoundingClientRect().top
  • distance >= 0 表示 图片的顶部已经进入可视区域
  • distance < 0 表示 图片还在屏幕下方,没有出现

3. 画图理解

假设浏览器窗口高 600px,所以 viewHeight = 600

┌────────────────────────────┐
│   ← 窗口顶部 (top = 0)     │
│                            │
│   [ 可视区域 600px 高度 ]   │
│                            │
│   ← 窗口底部 (top = 600)   │
└────────────────────────────┘

现在有三种情况:


(1) 图片在屏幕下方,还没出现

可视区底部 = 600
图片顶部   = 800
distance   = 600 - 800 = -200 (< 0)

👉 图片还没进入可视区。


(2) 图片刚好出现在屏幕底部

可视区底部 = 600
图片顶部   = 600
distance   = 600 - 600 = 0

👉 图片刚进入可视区。


(3) 图片已经完全进入屏幕

可视区底部 = 600
图片顶部   = 400
distance   = 600 - 400 = 200 (> 0)

👉 图片已经在可视区内,可以加载。


4. 总结一句话

viewHeight - imgs[i].getBoundingClientRect().top 👉 就是「窗口底部到图片顶部的距离」。 如果这个值 ≥ 0,说明图片已经出现在用户眼前,可以开始加载。