图片懒加载,就是滚动页面时,图片未出现在可视局域时不加载图片,只有图片出现在可视区域才加载。

思路:通过上面一段话,实现图片懒加载需要知道:

  • 绑定滚动事件
  • 可视窗口高度(VH)
  • 图片元素距离可视局域顶部距离(EH)
  • 如何加载图片

当VH大于EH时,图片出现在可视窗口,反之。

如何加载图片呢?我们可以为img标签绑定任意非其属性名的属性,将图片路径作为其属性值,例如:

<img data-src="./img/ec6c60c8c5de6d7fa899807cfa8d46f1.jpeg" alt="">
<img imgUrl="./img/ec6c60c8c5de6d7fa899807cfa8d46f1.jpeg" alt="">
<img aabbc="./img/ec6c60c8c5de6d7fa899807cfa8d46f1.jpeg" alt="">

都是可以的,这里我们使用

<img data-src="./img/ec6c60c8c5de6d7fa899807cfa8d46f1.jpeg" alt="">

来举例子:

首先需要获取img元素的DOM对象集合

let imgs = document.querySelectorAll('img')

遍历img的DOM对象集合,获取每个img的DOM对象

imgs.forEach(item => {
// 获取到每个img距离可视区域顶部的距离和可视局域的高度,并进行比较
if (item.getBoundingClientRect().top < window.innerHeight) {
// 获取元素属性为data-src的属性值,并赋值给imgDOM实例的src属性上
item.setAttribute('src',item.getAttribute('data-src'))
}
})

通过DOM对象的getBoundingClientRect().top获取该元素距离视口顶部的高度,通过window.innerHeight获取到视口高度。

item.getAttribute('data-src'):表示获取该DOM对象上名data-src属性的属性值。

item.setAttribute(attributeName,attributeValue):表示将attributeValue值作为属性值赋值给attributeName属性。

此时我们需要绑定一个滚动事件,这个事件绑定给window,每次只要滚动条发生滚动都会触发:

  let imgs = document.querySelectorAll('img')
// 为window绑定滚动事件
window.addEventListener('scroll', (e) => {
// 遍历img的DOM对象集合,获取每个img的DOM对象
mgs.forEach(item => {
// 获取到每个img距离可视区域顶部的距离和可视局域的高度,并进行比较
if (item.getBoundingClientRect().top < window.innerHeight) {
//获取元素属性为data-src的属性值,并赋值给imgDOM实例的src属性上
item.setAttribute('src',item.getAttribute('data-src'))
}
})
})

这是会有一个问题,就是每次滚动都会触发滚动事件,这会导致资源加载过多,浪费资源。

这里给出的解决方法有三个,

2,考虑兼容性:使用防抖或者节流

这里使用节流来举例(防抖可以自己去实现)

<script>
// 1获取img元素的DOM对象
let imgs = document.querySelectorAll('img')
// 为window绑定滚动事件
window.addEventListener('scroll', imgLazyLoading())
function imgLazyLoading() {
let timer
return () => {
if (timer) {
return;
}
timer = setTimeout(() => {
imgs.forEach(item => {
// 获取到每个img距离可视区域顶部的距离和可视局域的高度,并进行比较
if (item.getBoundingClientRect().top < window.innerHeight) {
// 获取元素属性为data-src的属性值,并赋值给imgDOM实例的src属性上
item.setAttribute('src', item.getAttribute('data-src'))
}
})
timer = null
}, 500)
}
}
</script>

节流或者防抖也会导致图片加载过多,但是比起不加,这种方式更加节省浏览器资源。

3,不考虑兼容性

使用IntersectionObserver构造函数(浏览器提供的构造函数,有些浏览器不支持)。这个是可以实现交叉观察,什么是交叉观察呢?就是可以知道目标元素和可视窗口是否发生交叉局域

IntersectionObserver构造函数提供了两个方法用于对目标元素进行观察和取消观察。

observe(DOM节点):观察元素

unobserve(DOM节点):取消观察

创建实例:

  let observer=new  IntersectionObserver(callBack)

callBack是一个回调函数,它执行两次,一次是目标元素和可视窗口发生交叉时调用,一次是不发生交叉时调用(看见时调用一次,看不见时调用一次)

callBack回调函数接收一个参数,该参数包含被观察DOM节点相关信息和观察状态的数组,其中我们需要的是每个数组项中的:

target:被观察的DOM节点实例

isIntersecting:是否被观察到,观察到的时候,我们只需要通过unobserve(DOM节点)取消观察。完成代码为:

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<style>
div {
height: 100vh;
width: 1000px;
position: relative;
top: 50%;
left: 50%;
transform: translate(50% 50%);
}
img {
padding-top: 50px;
margin-bottom: 50px;
height: 500px;
width: 500px;
background-repeat: no-repeat;
background-size: 100% 100%;
display: inline-block;
border-top: 2px solid red;
}
</style> <body>
<div>
<p>1111111111111111111111111111111111111111111111111111111111111111</p>
<p>22222222222222222222222222222222222222222222222222222222222222</p>
<p>3ewrw山东省地方第三方的范德萨发水电费第三方第三方电风扇方式对方水电费</p>
<p>11111111111111111111111111111111111111111111111111111111111111111</p>
<p>22222222222222222222222222222222222222222222222222222222222222</p>
<p>3ewrw山东省地方第三方的范德萨发水电费第三方第三方电风扇方式对方水电费</p>
<p>11111111111111111111111111111111111111111111111111111111111111111</p>
<p>22222222222222222222222222222222222222222222222222222222222222</p>
<p>3ewrw山东省地方第三方的范德萨发水电费第三方第三方电风扇方式对方水电费</p>
<p>11111111111111111111111111111111111111111111111111111111111111111</p>
<p>22222222222222222222222222222222222222222222222222222222222222</p>
<p>3ewrw山东省地方第三方的范德萨发水电费第三方第三方电风扇方式对方水电费</p>
<p>11111111111111111111111111111111111111111111111111111111111111111</p>
<p>22222222222222222222222222222222222222222222222222222222222222</p>
<p>3ewrw山东省地方第三方的范德萨发水电费第三方第三方电风扇方式对方水电费</p>
<p>1111111111111111111111111111111111111111111111111111111111111111</p>
<p>22222222222222222222222222222222222222222222222222222222222222</p>
<p>3ewrw山东省地方第三方的范德萨发水电费第三方第三方电风扇方式对方水电费</p>
<p>1111111111111111111111111111111111111111111111111111111111111111</p>
<p>22222222222222222222222222222222222222222222222222222222222222</p>
<p>3ewrw山东省地方第三方的范德萨发水电费第三方第三方电风扇方式对方水电费</p>
<p>1111111111111111111111111111111111111111111111111111111111111111</p>
<p>22222222222222222222222222222222222222222222222222222222222222</p>
<p>3ewrw山东省地方第三方的范德萨发水电费第三方第三方电风扇方式对方水电费</p>
<img data-src="./img/7ff513a853b6d50887606dc436b1ddff.jpeg" alt="">
<img data-src="./img/8a728780b5ddd5672eb5bf8a4ce23c86.jpeg" alt="">
<img data-src="./img/ec6c60c8c5de6d7fa899807cfa8d46f1.jpeg" alt="">
<img data-src="./img/7ff513a853b6d50887606dc436b1ddff.jpeg" alt="">
<img data-src="./img/8a728780b5ddd5672eb5bf8a4ce23c86.jpeg" alt="">
<img data-src="./img/ec6c60c8c5de6d7fa899807cfa8d46f1.jpeg" alt="">
<p>22222222222222222222222222222222222222222222222222222222222222</p>
<p>3ewrw山东省地方第三方的范德萨发水电费第三方第三方电风扇方式对方水电费</p>
<p>1111111111111111111111111111111111111111111111111111111111111111</p>
<p>22222222222222222222222222222222222222222222222222222222222222</p>
<p>3ewrw山东省地方第三方的范德萨发水电费第三方第三方电风扇方式对方水电费</p>
<p>1111111111111111111111111111111111111111111111111111111111111111</p>
<p>22222222222222222222222222222222222222222222222222222222222222</p>
<p>3ewrw山东省地方第三方的范德萨发水电费第三方第三方电风扇方式对方水电费</p>
<p>1111111111111111111111111111111111111111111111111111111111111111</p>
<p>22222222222222222222222222222222222222222222222222222222222222</p>
</div>
</body>
<script>
let imgs = document.querySelectorAll('img')
let observer=new IntersectionObserver(callBack)
imgs.forEach(imgItem=>{
// 观察节点,触发new IntersectionObserver(callBack)内的回调函数
observer.observe(imgItem)
})
// IntersectionObserver会向回调函数传入一个参数
function callBack(observerArray){
// observerArray:每个被观察元素对象的实例和观察状态集合
observerArray.forEach(item=>{
// item:被观察元素对象的实例和观察状态信息
// isIntersecting:是否被观察到
if(item.isIntersecting){
// item.target:被观察到实例
let imgDom=item.target
imgDom.setAttribute('src', imgDom.getAttribute('data-src'))
// 被观察到取消观察
observer.unobserve(imgDom)
}
console.log(item);
})
}
</script>
</html>

(LEARN FROM 技术蛋老师)

看都看到这了,点个赞吧,大晚上的写也不容易~~~~~算我球球你了(AQA)

JavaScript小面试~~JavaScript实现图片懒加载,多方式解决加载过多问题的更多相关文章

  1. 基于javascript实现图片懒加载(亲测有效)

    这篇文章主要介绍了javascript实现图片懒加载的方法及思路,有时我们需要用懒加载,也就是延迟加载图片的方式,来提高网站的亲和力,需要的朋友可以参考下! 一.定义 图片延迟加载也称为懒加载,延迟加 ...

  2. javascript图片懒加载与预加载的分析

    javascript图片懒加载与预加载的分析 懒加载与预加载的基本概念.  懒加载也叫延迟加载:前一篇文章有介绍:JS图片延迟加载 延迟加载图片或符合某些条件时才加载某些图片. 预加载:提前加载图片, ...

  3. JavaScript之图片懒加载的实现

    图片懒加载指的是在浏览过程中随着需要才被加载出来,例如某宝上面浏览商品时,会伴随很多的图片,如果一次全部加载出来的话,显然资源有些浪费,并且加载速度也会相对降低,那么懒加载的实现很重要.即随着浏览翻阅 ...

  4. js, javascript 图片懒加载 实例代码

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  5. javascript原生图片懒加载

    一,原生javascript图片懒加载 1. 使用方法,例如 // 要绑定的图片地址 <img data-src={url} alt=" "> 2. 在页面中引入下列原 ...

  6. Javascript图片懒加载

    懒加载的意义 懒加载的主要目的是作为服务器前端的优化,减少请求数或延迟请求数. 懒加载的实现 1.第一种是纯粹的延迟加载,使用setTimeOut或setInterval进行加载延迟. 2.第二种是条 ...

  7. JavaScript——图片懒加载

    前言 有一个朋友问我这个问题,刚好有时间,现在就简单的写个Demo~ github | https://github.com/wangyang0210/bky/tree/picLoadLazy 内容 ...

  8. 微信小程序的图片懒加载

    在普通的web页面当中,我们都知道图片懒加载可以提升浏览器的加载速度.原理是图片用空或者占位图片进行显示,当屏幕移动到图片位置的时候,再把图片的地址换成它的地址.那么,在小程序当中呢,最近老大让看一下 ...

  9. JS图片懒加载

    简介 当页面图片太多时,加载速度就会很慢.尤其是用2G/3G/4G访问页面,不仅页面慢,而且还会用掉很多流量.图片懒加载的原理就是将页面内所有需要加载的图片全部换成一张默认的图片(一般尺寸很小),只有 ...

  10. 前端性能优化--图片懒加载(lazyload image)

    话说前头: 上次写了一篇webpack的学习心得,webpack能做到提升前端的性能,其模块打包最终生成一个或少量的文件能够减少对服务端的请求.除此之外,本次的图片懒加载(当然不仅限于图片,还可以有视 ...

随机推荐

  1. 从源码的角度弄懂MyBatis动态代理开发原理

    MyBatis提供了一种动态代理实现SQL调用的功能,使用者只需要在映射文件中配置SQL语句与映射规则即可完成SQL调用和结果集封装.下面代码展示了动态代理调用的基本步骤: public void t ...

  2. linux中磁盘清理方法(简单好用)

    文章目录1.命令2.df参数说明3.find参数说明4.清理日志文件1.命令先来看解决办法 df -h --显示当前磁盘使用情况cd / --cd到要清理文件的路径下面find . -type f - ...

  3. 微服务实践k8s&dapr开发部署实验(3)订阅发布

    自托管模式运行dapr 新建订阅webapi项目,取名为backend 项目增加docker支持,取消https支持 修改Program.cs var builder = WebApplication ...

  4. Understanding Swift’s value type thread safety - 代码分析(二)

    示范代码 ` func testScenarioA2() throws { var store: Int = 100 DispatchQueue.concurrentPerform(iteration ...

  5. 【Azure App Service】.NET代码实验App Service应用中获取TLS/SSL 证书 (App Service Linux/Linux Container)

    在前一篇文章中,我们是把.NET 8应用读取SSL证书(X509)示例部署在App Service Windows环境中,那么如果部署在Linux环境,以及Linux Container中呢? 根据前 ...

  6. c# Redis缓存的使用和helper类;

    使用背景: 项目中用户频繁访问数据库会导致程序的卡顿,甚至堵塞.使用缓存可以有效的降低用户访问数据库的频次,有效的减少并发的压力.保护后端真实的服务器. 对于开发人员需要方便调用,所以本文提供了hel ...

  7. html2canvas + jspdf导出pdf,文字重叠,样式不显示或者文字不显示

    先在html引入cdn <script src="https://html2canvas.hertzen.com/dist/html2canvas.js"></s ...

  8. CSP-S2019 题解

    做了这套题,如果是让现在的我当时去考的话应该一共可以有 450 分,格雷码,括号树,树的重心都可以做,树上的数可以有 10 分,Emiya 至少可以有 76 分, 划分也可以有 64 分.看 OIer ...

  9. 如何解决Win10删除文件慢的办法

    问题:最近使用KMS激活了一些工具,今天删除不需要的文件时发现删除文件很慢很慢,删除一个几百k的文件都很慢. 解决办法通过控制面板→管理工具→服务→找到该进程并设为禁用就OK了.

  10. mysql case when使用

    ## mysql case when使用 SELECT order_no,case is_test when 0 then '否'when 1 then '是'end as '是否测试' from ` ...