位置: IT常识 - 正文

【前端】图片懒加载的原理和三种实现方式(前端image)

编辑:rootadmin
【前端】图片懒加载的原理和三种实现方式 一. 图片懒加载的目的

推荐整理分享【前端】图片懒加载的原理和三种实现方式(前端image),希望有所帮助,仅作参考,欢迎阅读内容。

文章相关热门搜索词:前端图片库,前端图片模糊的原因,前端图片库,前端实现图片编辑,前端实现图片编辑,前端图片展示,前端图片库,前端图片展示,内容如对您有帮助,希望把文章链接给更多的朋友!

大型网站如常用的淘宝,京东等页面,需要展示大量的商品图片信息,如果打开网页时让所有图片一次性加载完成,需要处理很多次网络请求,等待加载时间比较长,用户体验感很差。

有一种常用的解决方式是:随着滚动动态加载,即图片的惰性加载。视图之外的图片默认不加载,随着页面的滚动,图片进入了显示的范围,则触发图片的加载显示。

优点:页面加载速度快,用户体验感更好且节省流量

二. 图片懒加载的原理方法

初始化时,图片标签的src不能是真实的图片地址,也不可以是空地址或者坏地址(会出现图片加载失败的图标)。

初始化的时候,可以设置图片的src是某一个小型图片。例如一张1px*1px的透明图片。由于所有图片都使用这一张图片,只会发送一次请求,不会增加性能负担。将图片的真实路径绑定给一个自定义属性,例如data-url。注意:页面的img元素,如果没有src属性,浏览器就不会发出请求去下载图片<img data-url="xxx" src="1px.gif" width="100" height="100"/>定义滚动事件,判断元素进入视口,则将src替换为真正的url地址。利用js提取data-url的真实图片地址赋值给src属性三. 图片懒加载的实现方法

图片懒加载的关键在于获取元素的位置,并判断其是否出现在视口。故有以下三种方式

滚动监听+scrollTop+offsetTop+innerHeight滚动监听+getBoundingClientRect()intersectionObserve()3.1 滚动监听+scrollTop+offsetTop+innerHeight

scrollTop:指网页元素被滚动条卷去的部分。

offsetTop:元素相对父元素的位置

innerHeight:当前浏览器窗口的大小。需要注意兼容性问题。

IE8及更早版本以前没有提供取得浏览器窗口大小的属性,不过提供了API:document.documentElement.clientHeight/clientWidth:返回元素内容及其内边距所占据的空间大小。IE6中,上述属性必须在标准模式才有效,如果是混杂模式,需要通过document.body.clientWidth 和 document.body. clientHeight 取得相同信息。var pageWidth = window.innerWidthvar pageHeight = window.innerHeight; if (typeof pageWidth != "number"){ //pageWidth的值不是数值,说明没有innerwidth属性 if (document.compatMode == "CSS1Compat"){ //标准模式 pageWidth = document.documentElement.clientWidth; pageHeight = document.documentElement.clientHeight; } else { //混杂模式 pageWidth = document.body.clientWidth; pageHeight = document.body.clientHeight; } }三个属性之间的关系如图所示,故当scrollTop+innerHeight > offsetTop,即图片在视口内,否则图片在可视区域外。 代码实现

滚动监听完成图片懒加载的简易版本

<!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> <style> * { margin: 0; padding: 0; } img { margin-top:400px; width: 250px; display: block; } </style></head><body> <img src="img/1pxImg.png" data-url="img/1.jpg"> <img src="img/1pxImg.png" data-url="img/2.jpg"> <img src="img/1pxImg.png" data-url="img/3.jpg"> <img src="img/1pxImg.png" data-url="img/4.jpg"> <img src="img/1pxImg.png" data-url="img/5.jpg"> <script> var imgs = document.getElementsByTagName('img') scrollFn() // 监听滚动事件 window.onscroll = scrollFn function scrollFn() { var clietH = window.innerHeight || document.documentElement.clientHeight || document.body.clientHeight; var scrollTop = document.documentElement.scrollTop || window.pageYOffset || document.body.scrollTop; console.log(clietH, scrollTop); Array.from(imgs).forEach((item) =>{ let eleTop = item.offsetTop // console.log(eleTop) let count = scrollTop + clietH - eleTop console.log(count) // 可设置为>100 查看懒加载效果 if (count > 0) { //从data-url中取出真实的图片地址赋值给scr item.setAttribute('src', item.getAttribute('data-url')) } }) } </script></body></html>3.2 滚动监听+getBoundingClientRect()getBoundingClientRect()【前端】图片懒加载的原理和三种实现方式(前端image)

Element.getBoundingClientRect() 方法返回元素的大小及其相对于视口的位置。返回一个对象,对象属性包括top,right

rectObject = object.getBoundingClientRect();

API返回一个对象,即rectObject为一个对象,其包含以下属性

rectObject.top:元素上边到视窗上边的距离;rectObject.right:元素右边到视窗左边的距离;rectObject.bottom:元素下边到视窗上边的距离;rectObject.left:元素左边到视窗左边的距离;rectObject.width:元素自身的宽度rectObject.height:元素自身的高度

故当rectObject.top的值处于0-视口高度,则元素处于可视区。即getBoundingClientRect(ele).top >= 0 && getBoundingClientRect(ele).top <= offsetHeight代码实现<!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> <style> * { margin: 0; padding: 0; } img { margin-top:400px; width: 250px; display: block; } </style></head><body> <img src="img/1pxImg.png" data-url="img/1.jpg"> <img src="img/1pxImg.png" data-url="img/2.jpg"> <img src="img/1pxImg.png" data-url="img/3.jpg"> <img src="img/1pxImg.png" data-url="img/4.jpg"> <img src="img/1pxImg.png" data-url="img/5.jpg"> <script> var imgs = document.getElementsByTagName('img') scrollFn() // 监听滚动事件 window.onscroll = scrollFn function scrollFn() { var clietH = window.innerHeight || document.documentElement.clientHeight || document.body.clientHeight; Array.from(imgs).forEach((item) =>{ let ele = item.getBoundingClientRect() console.log(clietH,ele.top) // 可以设置为ele.top+200 查看懒加载效果 if (ele.top > 0 && ele.top < clietH) { //从data-url中取出真实的图片地址赋值给scr item.setAttribute('src', item.getAttribute('data-url')) } }) } </script></body></html>3.3 intersectionObserve()intersectionObserve()

新的API,针对元素的可见时间进行监听。由于可见(visible)的本质是,目标元素与视口产生一个交叉区,所以这个 API 叫做"交叉观察器"。

var io = new IntersectionObserver(callback, option);

IntersectionObserver是浏览器原生提供的构造函数,接受两个参数:callback是可见性变化时的回调函数,option是配置对象(该参数可选)。

构造函数的返回值是一个观察器实例。实例的observe方法可以指定观察哪个 DOM 节点。

// 开始观察io.observe(document.getElementById('example'));// 停止观察io.unobserve(element);// 关闭观察器io.disconnect();

上面代码中,observe的参数是一个 DOM 节点对象。如果要观察多个节点,就要多次调用这个方法。

io.observe(elementA);io.observe(elementB);callack参数

目标元素的可见性变化时,就会调用观察器的回调函数callback。

一般会触发两次:1.目标元素刚刚进入视口(开始可见),2.完全离开视口(开始不可见)。

callback函数的参数是一个数组,每个成员都是一个IntersectionObserverEntry对象。

IntersectionObserverEntry 对象

提供目标元素的信息,一共有六个属性。

time:可见性发生变化的时间,是一个高精度时间戳,单位为毫秒target:被观察的目标元素,是一个 DOM 节点对象rootBounds:根元素的矩形区域的信息,getBoundingClientRect()方法的返回值,如果没有根元素(即直接相对于视口滚动),则返回nullboundingClientRect:目标元素的矩形区域的信息intersectionRect:目标元素与视口(或根元素)的交叉区域的信息intersectionRatio:目标元素的可见比例,即intersectionRect占boundingClientRect的比例,完全可见时为1,完全不可见时小于等于0

所以可以通过判断intersectionRatio属性是否处于(0,1)来判断元素的可见性

代码实现<!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> <style> * { margin: 0; padding: 0; } img { margin-top:400px; width: 250px; display: block; } </style></head><body> <img src="img/1pxImg.png" data-url="img/1.jpg"> <img src="img/1pxImg.png" data-url="img/2.jpg"> <img src="img/1pxImg.png" data-url="img/3.jpg"> <img src="img/1pxImg.png" data-url="img/4.jpg"> <img src="img/1pxImg.png" data-url="img/5.jpg"> <script> var imgs = document.getElementsByTagName('img') // 观察器实例 let io = new IntersectionObserver((entires) =>{ entires.forEach(item => { // 原图片元素 let oImg = item.target if (item.intersectionRatio > 0 && item.intersectionRatio <= 1) { oImg.setAttribute('src', oImg.getAttribute('data-url')) } }) }) // 给每一个图片设置观察器 Array.from(imgs).forEach(element => { io.observe(element) }); </script></body></html>

备注:本文章为学习前端知识过程中的记录和分享,如有错误欢迎指正!

本文链接地址:https://www.jiuchutong.com/zhishi/300304.html 转载请保留说明!

上一篇:网络安全工具大合集(网络安全工具大全图片)

下一篇:计算机视觉项目-实时目标追踪(计算机视觉项目队友只让你打标签是什么意思)

  • 4个让你宝贝卖疯的淘宝店铺推广技巧(4个让你宝贝卖的女人)

    4个让你宝贝卖疯的淘宝店铺推广技巧(4个让你宝贝卖的女人)

  • opporeno7pro防水吗(oppor17pro防水)

    opporeno7pro防水吗(oppor17pro防水)

  • vivox70晚上怎么拍夜景(vivo手机怎么设置晚上自动关机)

    vivox70晚上怎么拍夜景(vivo手机怎么设置晚上自动关机)

  • 花呗怎样开通(花呗怎样开通商家花呗收款)

    花呗怎样开通(花呗怎样开通商家花呗收款)

  • 荣耀x10不能用4g卡吗(华为荣耀x10为什么不可以用5g)

    荣耀x10不能用4g卡吗(华为荣耀x10为什么不可以用5g)

  • 华为nova4反应太慢怎么办(华为nova4太卡怎么办)

    华为nova4反应太慢怎么办(华为nova4太卡怎么办)

  • 一加七和一加七pro对比(一加七和一加七pro续航)

    一加七和一加七pro对比(一加七和一加七pro续航)

  • 苹果手机的抖音充值在哪里(苹果手机的抖音怎么更新)

    苹果手机的抖音充值在哪里(苹果手机的抖音怎么更新)

  • 微信怎样发平均红包(微信怎样发平均红包_生活知识)

    微信怎样发平均红包(微信怎样发平均红包_生活知识)

  • se支持无线充电吗(se支持无线充电功能吗)

    se支持无线充电吗(se支持无线充电功能吗)

  • 耳机插手机没声音(耳机插手机没声音是什么意思)

    耳机插手机没声音(耳机插手机没声音是什么意思)

  • 荣耀9x与华为nova5i对比(荣耀9x与华为nove9se)

    荣耀9x与华为nova5i对比(荣耀9x与华为nove9se)

  • word文档的文字超出了页面边框(word文档的文字怎么竖排)

    word文档的文字超出了页面边框(word文档的文字怎么竖排)

  • 无线鼠标的电池是几号(无线鼠标的电池可以用普通的五号电池吗)

    无线鼠标的电池是几号(无线鼠标的电池可以用普通的五号电池吗)

  • 计算机什么是承载CPU(计算机什么是承载CPU、BIOS和内存等器件的部分)

    计算机什么是承载CPU(计算机什么是承载CPU、BIOS和内存等器件的部分)

  • macpro是什么东西(苹果macpro是什么)

    macpro是什么东西(苹果macpro是什么)

  • 抖音推广位是什么意思(抖音广告位推广)

    抖音推广位是什么意思(抖音广告位推广)

  • 别人发的微信表情包不显示(别人发的微信表情怎么添加到表情包)

    别人发的微信表情包不显示(别人发的微信表情怎么添加到表情包)

  • 为什么网易云音乐下载不了(为什么网易云音乐分享到朋友圈没有播放键)

    为什么网易云音乐下载不了(为什么网易云音乐分享到朋友圈没有播放键)

  • 抖音每天直播多长时间(抖音每天直播多少个小时能挣钱)

    抖音每天直播多长时间(抖音每天直播多少个小时能挣钱)

  • 淘宝短视频怎么保存(淘宝短视频怎么制作)

    淘宝短视频怎么保存(淘宝短视频怎么制作)

  • 苹果手机的小圆点怎么关闭(苹果手机的小圆点不见了怎么找回)

    苹果手机的小圆点怎么关闭(苹果手机的小圆点不见了怎么找回)

  • 固态硬盘mlc和tlc区别(固态硬盘mlc和tlc怎么分辨)

    固态硬盘mlc和tlc区别(固态硬盘mlc和tlc怎么分辨)

  • 华为mate30pro相册在哪里(华为mate30pro相册隐藏如何恢复)

    华为mate30pro相册在哪里(华为mate30pro相册隐藏如何恢复)

  • 华为gt3什么时候出

    华为gt3什么时候出

  • 淘宝乡村版怎么设置(淘宝乡村版怎么返回标准版)

    淘宝乡村版怎么设置(淘宝乡村版怎么返回标准版)

  • 快手不更新是怎么回事(快手不更新怎么设置)

    快手不更新是怎么回事(快手不更新怎么设置)

  • 爱奇艺多屏互动怎么开(爱奇艺多屏互动怎么连接电视)

    爱奇艺多屏互动怎么开(爱奇艺多屏互动怎么连接电视)

  • 华为p30如何设置铃声(华为p30如何设置24小时制)

    华为p30如何设置铃声(华为p30如何设置24小时制)

  • 如何重装系统win10?(如何重装系统win7旗舰版)

    如何重装系统win10?(如何重装系统win7旗舰版)

  • 个人应纳税所得额20万交多少税
  • 所得税为什么比利润高
  • 其他综合收益属于当期损益吗
  • 向银行借款存入银行会引起
  • 所得税申报表收入
  • 申报财务报表时应收和预收可以合并
  • 土地使用权出让金多少钱一平米
  • 托收承付怎么理解
  • 成品油发票如何同步
  • 公司股东投资是负债吗
  • 财务发票已开但钱未到位怎么处理?
  • 增值税附加税什么情况交
  • 利润表里的营业税金及附加如何计算
  • 企业债务追诉期几年
  • 与权益法核算相关的累计净损益
  • 发票认证只认证进项吗
  • 大学食堂外包的优点与缺点
  • 出售交易性金融资产的记账凭证
  • 农业合作社出售农产品怎么计税
  • 销售门窗并安装如何缴纳增值税
  • 重置组策略命令
  • 税务部门罚没收入计入什么科目
  • 电脑怎样进入cmos设置
  • 电子商票到期后多少天有效?
  • 已缴税额比应纳税额多
  • ngwatch.exe
  • ios 的 safari 浏览器
  • win7系统安装包多大
  • 矿产资源补偿费是什么
  • 招行网银专业版怎么登陆
  • 固定资产生产经营期间正常报废产生的净收益
  • springboot整合ssm
  • chat top
  • 为什么会有不同的人种
  • vue解决跨域的几种办法
  • 公司管理费一般占多少个点
  • 资产负债表和利润表的勾稽关系
  • 分公司需要做纳税申报吗
  • 公司盖厂房没有票要交税吗?
  • mysql报错1227
  • mongodb索引存储方式
  • mongodb主键
  • 织梦怎么样
  • 政府扶持资金所得税税率
  • 会计电算化的内容和任务
  • 研发费用如何进账
  • 增值税税控系统专用设备费及技术维护费抵扣
  • 进出口 外汇
  • 银行付款明细
  • 物业公司劳务外包
  • 赞助支出属于什么科目
  • 补交增值税税款怎么做账
  • 出口退税的会计分录为什么在贷方
  • 独立核算的单位是什么意思
  • 违约投标保证金多少
  • 递延所得税资产是什么意思
  • 注册资本金印花税税率是2.5还是5
  • 工厂的委托加工怎么写
  • 空头支票是什么数字
  • 签发空头支票的罚款
  • win7系统IE浏览器打开跳转到360浏览器,怎么阻止
  • 怎么判断win7还是win10
  • 远程管理是什么意思
  • nw.exe是什么进程
  • linux的ftp命令
  • centos 文件搜索
  • linux系统中的脚本文件一般以什么开头
  • Windows10 Redstone首个预览版即将发布 开始推送全新的预览分支
  • win7运行速度
  • node管理工具
  • android RecycleView 面试
  • 老生常谈的错别字
  • bat读取文件内所有内容
  • 什么叫屏蔽屏幕按键
  • python字符串常用方法
  • div遮罩层整个页面
  • vue用户权限解决方案
  • Python线程进程协程
  • 我是一般纳税人对方给我开的普票
  • 江苏企业所得税税率2023
  • 免责声明:网站部分图片文字素材来源于网络,如有侵权,请及时告知,我们会第一时间删除,谢谢! 邮箱:opceo@qq.com

    鄂ICP备2023003026号

    网站地图: 企业信息 工商信息 财税知识 网络常识 编程技术

    友情链接: 武汉网站建设