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

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

  • 绑定滚动事件
  • 可视窗口高度(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. winform 使用Clipboard 和windows Word Com组件 把Html 导出到word

    首先是把Html复制到剪贴板 见:https://www.cnblogs.com/HelloQLQ/p/16289343.html 然后使用: private void saveAsWordCopy( ...

  2. SpringAi

    Spring AI 初学 Spring AI 官方地址 "spring 不生产 AI,只是 AI 工具的搬运工" 项目可以查看gitee Open AI 前期准备 Open AI官 ...

  3. C# 实现中文转颜色 - 实现根据名字自动生成头像

    一.C#实现中文转颜色 - 实现根据名字自动生成头像 原理说明: 由于名字图像是自动生成,背景颜色不一样,可以考虑一下几种方法: 1)使用随机数来自动生成一个16进制颜色字符串,作为头像的背景颜色: ...

  4. nginx对称加密算法和非对称加密算法nginx证书配置

    对称加密算法 对称加密性能更好 对称加密: 客户端和服务器之间的通信数据是通过对称加密算法进行加密,对称加密是在加密和解密的过程中使用同一个私钥进行加密和解密,而且加密算法是公开的,所以对称加密中的私 ...

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

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

  6. Windows平台git clone文件路径太长报错

    问题描述 在Windows下拉取一些比较大的开源项目经常会提示文件路径太长(filename too long),然后死活都不成功 解决办法 1.配置git git config --system c ...

  7. 震惊!docker镜像还有这些知识,你都知道吗?----镜像(一)

    镜像操作命令表格 docker image 子命令 docker子命令 功能 docker image build docker build 从Dockerfile开始构建镜像 docker imag ...

  8. aspose word与pdf互转

    aspose word与pdf互转 package com.example.core.mydemo.aspose; import com.aspose.words.Document; import c ...

  9. 接口签名规则及Java代码demo实现

    接口签名规则及Java代码demo实现 签名规则 签名生成的通用步骤如下: 第一步,设所有发送或者接收到的数据为集合M,将集合M内非空参数值的参数按照参数名ASCII码从小到大排序(字典序),使用UR ...

  10. Java与React轻松导出Excel/PDF数据

    前言 在B/S架构中,服务端导出是一种高效的方式.它将导出的逻辑放在服务端,前端仅需发起请求即可.通过在服务端完成导出后,前端再下载文件完成整个导出过程.服务端导出具有许多优点,如数据安全.适用于大规 ...