Lambda博客
  • 自我介绍
  • SSR
    • 浅谈SSR
  • React
    • 页面路由——React-Router
    • 管好你的状态——React-Redux
    • 一个哪行——React详解
    • 左膀右臂一个不少——React初探
  • 问题记录
    • js-xlsx实现纯前端导出excel表格
    • 前端开发需要了解的东西
    • 打造高性能网站
  • JavaScript学习笔记
    • 语法和API
    • js-垃圾回收
    • 收集的JS使用技巧
    • 执行机制
    • 原型和原型链
    • 执行上下文
    • 事件循环
    • JavaScript手写代码
    • 43道JS面试题
    • 悄悄的带走了你的东西——闭包详解
    • 你是个富二代吗?——JavaScript作用域链
    • 捉摸不透的女生——JavaScript类型转换
    • 这是你的女神!——JavaScript
  • 网络学习笔记
    • 强不强——HTTP-协商缓存VS强缓存
    • 网络缓存
    • 我要飞的更高——计算机网络
    • 快点!再快点!——CDN
    • 喜怒哀乐多状态——HTTP状态码
    • 你会爱上我的(ಥ_ಥ) ——TCP详解
    • 隔壁老王想篡位?门都没有——同源策略
  • 软技能
  • 安全专题
    • 保护好自己——网站安全,预防
  • 浏览器兼容性
    • 我是个好人——浏览器兼容性
  • 多图片加载——懒加载详解
  • 数据结构
  • Node
    • Node初探
  • Typescript
    • JS Plus 真香——初探 TypeScript
  • 设计模式
    • 不要花里胡哨,要一套一套——设计模式(1)
    • 学会“套路”——设计模式(2)
  • Vue
    • 实操实干——vue实例记录
    • 停下来,问问自己——Vue-刨根问底
    • 你有喘息的机会吗?——Vue,逐步了解
    • 你累吗?来来来,安利框架——Vue-初次见面
  • 小程序
    • 今天天气怎么样——记一次小程序开发
  • Webpack
    • 蛋糕分割整合工具——Webpack-前端工程化
  • 你一块,我一块——Web-modules 前端模块化
  • HTML5
    • 你会画小猪佩奇吗?—— canvas
    • 画个矢量图——HTML5-SVG
    • 听说你爱闹腾——HTML5-多媒体
    • 动画神器——HTML5-requestAnimationFrame
    • 留下痕迹——HTML5-客户端存储
    • 你知道指北针吗?——HTML5-DeviceMotionEvent
    • 你在哪啊?我在这啊——HTML5-Geolocation
    • 你到这,你到那——HTML5-拖拽
    • 你从这,到那——HTML5-拖拽上传文件
    • 开启前端之路——HTML 标签
  • 瀑布流(无限滚动)
  • 我是怎么来的?——浏览器渲染原理
  • Css
    • 由大变小,你行吗 —— 移动端
    • 动起来,这样比较炫—— CSS3 动画
    • 请不要拐弯抹角 —— CSS3 选择器
    • 想炫吗?—— CSS3 属性
    • 最后的最后——CSS自问自答
    • 万事开头难?——深入学习前端常见布局
    • 一入前端深似海——BFC剖析
    • 还有哪些好玩的东西——CSS提升
    • 那些好看的页面是怎么形成的——CSS 初识
  • 拿个小本本记下——Cookie
由 GitBook 提供支持
在本页
在GitHub上编辑

多图片加载——懒加载详解

懒加载

由于过多的图片会严重影响网页的加载速度,并且移动网络下的流量消耗巨大,所以说延迟加载几乎是标配了。

懒加载原理

图片懒加载的原理很简单,就是我们先设置图片的data-set属性(当然也可以是其他任意的,只要不会发送 http 请求就行了,作用就是为了存取值)值为其图片路径,由于不是src,所以不会发送 http 请求。 然后我们计算出页面 scrollTop 的高度和浏览器的高度之和, 如果图片举例页面顶端的坐标 Y(相对于整个页面,而不是浏览器窗口)小于前两者之和,就说明图片就要显示出来了(合适的时机,当然也可以是其他情况),这时候我们再将 data-set 属性替换为 src 属性即可。

手动实现一个懒加载

<div class="top">上边</div>
<img class="lazyload" data-src="https://s2.ax1x.com/2019/11/18/MsHSZ8.png" />
<img class="lazyload" data-src="https://s2.ax1x.com/2019/11/18/MsHSZ8.png" />
...
<div class="bottom">下边</div>
class StartLazy {
  constructor(defaultImg, timeout) {
    this.defaultImg = defaultImg
    this.timeout = timeout || 500
  }
  /**
   * 初始化
   * 或得到全部需要懒加载的图片资源
   * 设置上默认要显示的图片
   * 进行懒加载
   */
  init() {
    this.imgs = [...document.querySelectorAll('img[data-src]')]
    // 设置默认图片
    this.setDefaultImgs()
    // 懒加载所有
    this.loadAllImgs()
    const self = this
    let timer = null
    document.body.onscroll = function (params) {
      if (timer) {
        clearTimeout(timer)
      }
      timer = setTimeout(() => {
        self.loadAllImgs()
      }, self.timeout);
    }
  }

  /**
   * 设置上默认要显示图片
   */
  setDefaultImgs() {
    if (!this.defaultImg) {
      // 如果没有设置默认图片
      return
    }
    const imgs = this.imgs
    for (let i = 0; i < imgs.len; i++) {
      const img = imgs[i];
      img.src = defaultImg
    }
  }

  /**
   * 加载所有的图片
   */
  loadAllImgs() {
    const imgs = this.imgs
    for (let i = 0; i < imgs.length; i++) {
      const img = imgs[i]
      // 判断当前图片是否需要加载
      if (this.loadImg(img)) {
        // 去除掉已经加载的图片
        imgs.splice(i, 1)
        i--
      }

    }
  }

  /**
   * 懒加载一张图片
   * 判断是否应该加载
   */
  loadImg(img) {
    // 判断该图片是否能够加载,判断图片是否在可视区域内
    const rect = img.getBoundingClientRect()
    if (rect.bottom <= 0) {
      return false
    }
    if (rect.top >= document.documentElement.clientHeight) {
      return false
    }

    img.src = img.dataset.src

    // 判断是否有原图(大图)  进行预加载
    if (img.dataset.original) {
      // 等待图片加载完成
      img.onload = () => {
        img.src = img.dataset.original
        // 加载完成后清除事件
        img.onload - null
      }
    }
    return true
  }
}

// 使用
const lazyLoad = new StartLazy('loading.gif', 300)
lazyLoad.init()
上一页我是个好人——浏览器兼容性下一页数据结构

最后更新于3年前