JavaScript小面试~~JavaScript实现图片懒加载,多方式解决加载过多问题
图片懒加载,就是滚动页面时,图片未出现在可视局域时不加载图片,只有图片出现在可视区域才加载。
思路:通过上面一段话,实现图片懒加载需要知道:
- 绑定滚动事件
- 可视窗口高度(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实现图片懒加载,多方式解决加载过多问题的更多相关文章
- 基于javascript实现图片懒加载(亲测有效)
这篇文章主要介绍了javascript实现图片懒加载的方法及思路,有时我们需要用懒加载,也就是延迟加载图片的方式,来提高网站的亲和力,需要的朋友可以参考下! 一.定义 图片延迟加载也称为懒加载,延迟加 ...
- javascript图片懒加载与预加载的分析
javascript图片懒加载与预加载的分析 懒加载与预加载的基本概念. 懒加载也叫延迟加载:前一篇文章有介绍:JS图片延迟加载 延迟加载图片或符合某些条件时才加载某些图片. 预加载:提前加载图片, ...
- JavaScript之图片懒加载的实现
图片懒加载指的是在浏览过程中随着需要才被加载出来,例如某宝上面浏览商品时,会伴随很多的图片,如果一次全部加载出来的话,显然资源有些浪费,并且加载速度也会相对降低,那么懒加载的实现很重要.即随着浏览翻阅 ...
- js, javascript 图片懒加载 实例代码
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- javascript原生图片懒加载
一,原生javascript图片懒加载 1. 使用方法,例如 // 要绑定的图片地址 <img data-src={url} alt=" "> 2. 在页面中引入下列原 ...
- Javascript图片懒加载
懒加载的意义 懒加载的主要目的是作为服务器前端的优化,减少请求数或延迟请求数. 懒加载的实现 1.第一种是纯粹的延迟加载,使用setTimeOut或setInterval进行加载延迟. 2.第二种是条 ...
- JavaScript——图片懒加载
前言 有一个朋友问我这个问题,刚好有时间,现在就简单的写个Demo~ github | https://github.com/wangyang0210/bky/tree/picLoadLazy 内容 ...
- 微信小程序的图片懒加载
在普通的web页面当中,我们都知道图片懒加载可以提升浏览器的加载速度.原理是图片用空或者占位图片进行显示,当屏幕移动到图片位置的时候,再把图片的地址换成它的地址.那么,在小程序当中呢,最近老大让看一下 ...
- JS图片懒加载
简介 当页面图片太多时,加载速度就会很慢.尤其是用2G/3G/4G访问页面,不仅页面慢,而且还会用掉很多流量.图片懒加载的原理就是将页面内所有需要加载的图片全部换成一张默认的图片(一般尺寸很小),只有 ...
- 前端性能优化--图片懒加载(lazyload image)
话说前头: 上次写了一篇webpack的学习心得,webpack能做到提升前端的性能,其模块打包最终生成一个或少量的文件能够减少对服务端的请求.除此之外,本次的图片懒加载(当然不仅限于图片,还可以有视 ...
随机推荐
- HTML——table表格标签
一.table表格的完整写法 <!DOCTYPE html> <html> <head> <meta charset="utf-8"> ...
- zfile 在线云盘、网盘、OneDrive、云存储、私有云、对象存储、h5ai、上传、下载
基于 Java 的在线网盘程序,支持对接 S3.OneDrive.SharePoint.又拍云.本地存储.FTP.SFTP 等存储源,支持在线浏览图片.播放音视频,文本文件.Office.obj(3d ...
- Qt一键部署配置(Qt程序打包)
Qt一键部署配置(Qt程序打包) 1.版本 系统版本:windows10 Qt版本:5.15.2 2.设置可执行程序输出路径 打开.pro文件,输入DESTDIR = $$PWD/../bin,这 ...
- MySQL学习笔记-索引
索引 索引(index)是帮助MySQL高效获取数据的数据结构(有序).在数据之外,数据库系统还维护着满足特定查找算法的数据结构,这些数据结构以某种方式引用(指向)数据,这样就可以在这些数据结构上实现 ...
- Your Post Title Here
VSCode 实时预览还需要执行 Markdown: Open Preview to the Side 命令来实现. 在命令窗口输入 Markdown: Open Preview to the Sid ...
- shell脚本入门学习
1 参考 [尚硅谷]Shell脚本从入门到实战_哔哩哔哩_bilibili 本文为上面链接的课程学习记录. 2 基础 shell脚本需要shell解释器进行执行,shell解释器就是一个应用程序,有多 ...
- vue Ref 动态组件 keeplive
ref被用来给元素或子组件注册引用信息.引用信息将会注册在父组件的 $refs 对象上.如果在普通的 DOM 元素上使用,引用指向的就是 DOM 元素:如果用在子组件上,引用就指向组件实例 # 普通d ...
- C#.NET Framework RSA 公钥加密-私钥解密
C#.NET Framework RSA 公钥加密-私钥解密 加密解析: //假设私钥长度为1024, 1024/8-11=117. //如果明文的长度小于117,直接全加密,然后转base64.(d ...
- rsync备份任务练习
06-备份任务实战 今天的任务主要以实际备份任务入手,完成综合练习,完成对rsync的综合运用. 先看需求 再讲解 再次动手实践 客户端需求 客户端需求: 1.客户端每天凌晨1点在服务器本地打包备份( ...
- python写文件,过滤空行,根据某一行打上标记
import shutil import os ###第一步写文件 ''' with open('test.txt', 'w',encoding='utf-8') as f: f.write(&quo ...