亮神知识库 亮神知识库
首页
  • 手写代码

    • 手写代码系列
  • 基础知识

    • 基础
    • JS底层
    • CSS
  • 原理
  • 浏览器
  • HTTP
  • 网络安全
  • babel
  • webpack基础
  • webpack进阶
  • Vite
  • TypeScript
  • Vue2
  • Vue3
  • Node基础

    • glob
    • 模块化机制
    • 事件循环
    • KOA2框架原理
    • Node子进程
    • cluster原理(了解)
  • 教育行业2021

    • B端
    • C端
    • 工具
  • 游戏行业2025
  • 刷题
  • 杂(待整理)
  • 学习
  • 面试
  • 实用技巧
  • 心情杂货
  • 年度总结
  • 友情链接
关于
  • 分类
  • 标签
  • 归档
  • 收藏
GitHub (opens new window)

亮神

前程明亮,未来可期
首页
  • 手写代码

    • 手写代码系列
  • 基础知识

    • 基础
    • JS底层
    • CSS
  • 原理
  • 浏览器
  • HTTP
  • 网络安全
  • babel
  • webpack基础
  • webpack进阶
  • Vite
  • TypeScript
  • Vue2
  • Vue3
  • Node基础

    • glob
    • 模块化机制
    • 事件循环
    • KOA2框架原理
    • Node子进程
    • cluster原理(了解)
  • 教育行业2021

    • B端
    • C端
    • 工具
  • 游戏行业2025
  • 刷题
  • 杂(待整理)
  • 学习
  • 面试
  • 实用技巧
  • 心情杂货
  • 年度总结
  • 友情链接
关于
  • 分类
  • 标签
  • 归档
  • 收藏
GitHub (opens new window)
  • 基础

  • 手写代码

    • 手写类型转换
    • 手写累加、累乘函数
    • 手写new
    • 手写深拷贝
    • 手写Object.create
    • 手写继承
    • 手写extends
    • 手写instanceof
    • 手写call、apply、bind
    • 手写jsonp
    • 手写getQueryString
    • 手写setInterval
    • 手写防抖与节流
    • 手写对象属性值迭代器
    • 手写分时函数
    • 手写事件委托
    • 手写图片懒加载
    • 手写原生Ajax请求
    • 手写AOP装饰函数
    • 手写柯里函数
    • 手写数组扁平化flat
    • 手写数组去重
    • 手写eventEmit类
    • 手写Vue数据响应式
    • 手写Vue nextTick
    • 手写Promise
  • JS底层深入

  • CSS

  • 基础
  • 手写代码
0zcl
2021-06-18

手写图片懒加载

图片懒加载:img.src = 'xxx' 由于网络请求需要一定时间,会导致图片位置在加载过程中空白,故可以在图片加载中,先显示一个 <code>loading</code> 图片,待真正的图片加载完成,再显示。

注意

封装一个支付 promise 的图片加载方法,如: loadImg('https://avatars.githubusercontent.com/u/26007970?v=4').then(() => { })

答:

function loadImg(src) {
  return new Promise((resolve, reject) => {
    const img = new Image()
    img.onload = function() {
      resolve({
        width: img.width,
        height: img.height
      })
    }
    img.onerror = function(e) {
      console.log('load src error', src)
      reject(e)
    }
    img.src = src
  })
}

// 测试
loadImg('https://avatars.githubusercontent.com/u/26007970?v=4').then(res => {
  console.log('res', res) // {width: 62, height: 62}
})
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21

很简洁的代码吧😄, 这里加了点优化,loadImg 能返回图片的相关信息,如 宽和高

注意

实现图片懒加载

答:在调用<code>lazyLoad(dom, src)</code>时,就需要给dom.src = 'xxx' 先赋值为 loading 图片

function lazyLoad(dom, src) {
  const errorSrc = 'https://www.computerhope.com/jargon/e/error.png'
  const loadSrc = 'https://media0.giphy.com/media/3oEjI6SIIHBdRxXI40/giphy.gif'
  const img = new Image()
  img.onload = function() {
   dom.src = src 
  }
  img.onerror = function() {
    dom.src = errorSrc
  }
  img.src = src
  dom.src = loadSrc
}

// 测试
const dom = document.getElementById('lazy-load-img')
lazyLoad(dom, src)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

优化:每次调用lazyLoad都会生成 errorSrc, loadSrc, img 变量。这些变量能否 只生成一次就好了?

const lazyLoad = (function(src) {
  const errorSrc = 'https://www.computerhope.com/jargon/e/error.png'
  const loadSrc = 'https://media0.giphy.com/media/3oEjI6SIIHBdRxXI40/giphy.gif'
  const dom = document.getElementById('lazy-load-img')
  const img = new Image()
  img.onload = function() {
   dom.src = src 
  }
  img.onerror = function() {
    dom.src = errorSrc
  }
  return {
    setSrc: function(src) {
      img.src = src
      dom.src = loadSrc
    }
  }
})()

// 测试
lazyLoad.setSrc(src)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21

<button id="reload-button">重新加载图片</button>

编辑 (opens new window)
上次更新: 2025/07/12, 10:46:19
手写事件委托
手写原生Ajax请求

← 手写事件委托 手写原生Ajax请求→

最近更新
01
2024年
07-20
02
2023年
07-20
03
2022年
07-20
更多文章>
Theme by Vdoing | Copyright © 2025-2025 亮神 | MIT License | 桂ICP备2024034950号 | 桂公网安备45142202000030
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式