我的编程空间,编程开发者的网络收藏夹
学习永远不晚

web前端图片懒加载的原理与实现方式有哪些

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

web前端图片懒加载的原理与实现方式有哪些

这篇文章主要讲解了“web前端图片懒加载的原理与实现方式有哪些”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“web前端图片懒加载的原理与实现方式有哪些”吧!

    一. 图片懒加载的目的

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

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

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

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

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

    初始化的时候,可以设置图片的class="lazy" data-src是某一个小型图片。例如一张1px*1px的透明图片。由于所有图片都使用这一张图片,只会发送一次请求,不会增加性能负担。将图片的真实路径绑定给一个自定义属性,例如data-url。注意:页面的img元素,如果没有class="lazy" data-src属性,浏览器就不会发出请求去下载图片

    <img  data-url="xxx" class="lazy" data-src="1px.gif" width="100" height="100"/>

    定义滚动事件,判断元素进入视口,则将class="lazy" data-src替换为真正的url地址。利用js提取data-url的真实图片地址赋值给class="lazy" data-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 class="lazy" data-src="img/1pxImg.png" data-url="img/1.jpg">    <img class="lazy" data-src="img/1pxImg.png" data-url="img/2.jpg">    <img class="lazy" data-src="img/1pxImg.png" data-url="img/3.jpg">    <img class="lazy" data-src="img/1pxImg.png" data-url="img/4.jpg">    <img class="lazy" data-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('class="lazy" data-src', item.getAttribute('data-url'))                 }            })        }    </script></body></html>

    3.2 滚动监听+getBoundingClientRect() getBoundingClientRect()

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

    rectObject = object.getBoundingClientRect();

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

    • rectObject.top:元素上边到视窗上边的距离;

    • rectObject.right:元素右边到视窗左边的距离;

    • rectObject.bottom:元素下边到视窗上边的距离;

    • rectObject.left:元素左边到视窗左边的距离;

    • rectObject.width:元素自身的宽度

    • rectObject.height:元素自身的高度

    web前端图片懒加载的原理与实现方式有哪些

    故当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 class="lazy" data-src="img/1pxImg.png" data-url="img/1.jpg">    <img class="lazy" data-src="img/1pxImg.png" data-url="img/2.jpg">    <img class="lazy" data-src="img/1pxImg.png" data-url="img/3.jpg">    <img class="lazy" data-src="img/1pxImg.png" data-url="img/4.jpg">    <img class="lazy" data-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('class="lazy" data-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()方法的返回值,如果没有根元素(即直接相对于视口滚动),则返回null

    • boundingClientRect:目标元素的矩形区域的信息

    • 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 class="lazy" data-src="img/1pxImg.png" data-url="img/1.jpg">    <img class="lazy" data-src="img/1pxImg.png" data-url="img/2.jpg">    <img class="lazy" data-src="img/1pxImg.png" data-url="img/3.jpg">    <img class="lazy" data-src="img/1pxImg.png" data-url="img/4.jpg">    <img class="lazy" data-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('class="lazy" data-src', oImg.getAttribute('data-url'))                }             })        })       // 给每一个图片设置观察器        Array.from(imgs).forEach(element => {            io.observe(element)         });    </script></body></html>

    感谢各位的阅读,以上就是“web前端图片懒加载的原理与实现方式有哪些”的内容了,经过本文的学习后,相信大家对web前端图片懒加载的原理与实现方式有哪些这一问题有了更深刻的体会,具体使用情况还需要大家实践验证。这里是编程网,小编将为大家推送更多相关知识点的文章,欢迎关注!

    免责声明:

    ① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

    ② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

    web前端图片懒加载的原理与实现方式有哪些

    下载Word文档到电脑,方便收藏和打印~

    下载Word文档

    猜你喜欢

    web前端图片懒加载的原理与实现方式有哪些

    这篇文章主要讲解了“web前端图片懒加载的原理与实现方式有哪些”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“web前端图片懒加载的原理与实现方式有哪些”吧!一. 图片懒加载的目的大型网站如常
    2023-07-05

    前端图片懒加载的原理与3种实现方式举例

    图片懒加载又称图片延时加载、惰性加载,即在用户需要使用图片的时候加载,这样可以减少请求,节省带宽,提高页面加载速度,相对的,也能减少服务器压力,下面这篇文章主要给大家介绍了关于前端图片懒加载的原理与3种实现方式的相关资料,需要的朋友可以参考下
    2023-03-01

    JavaScript实用的图片懒加载优化方法有哪些

    这篇文章主要介绍了JavaScript实用的图片懒加载优化方法有哪些,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。一、方法一重点:1.getBoundingClientRec
    2023-06-29

    编程热搜

    • Python 学习之路 - Python
      一、安装Python34Windows在Python官网(https://www.python.org/downloads/)下载安装包并安装。Python的默认安装路径是:C:\Python34配置环境变量:【右键计算机】--》【属性】-
      Python 学习之路 - Python
    • chatgpt的中文全称是什么
      chatgpt的中文全称是生成型预训练变换模型。ChatGPT是什么ChatGPT是美国人工智能研究实验室OpenAI开发的一种全新聊天机器人模型,它能够通过学习和理解人类的语言来进行对话,还能根据聊天的上下文进行互动,并协助人类完成一系列
      chatgpt的中文全称是什么
    • C/C++中extern函数使用详解
    • C/C++可变参数的使用
      可变参数的使用方法远远不止以下几种,不过在C,C++中使用可变参数时要小心,在使用printf()等函数时传入的参数个数一定不能比前面的格式化字符串中的’%’符号个数少,否则会产生访问越界,运气不好的话还会导致程序崩溃
      C/C++可变参数的使用
    • css样式文件该放在哪里
    • php中数组下标必须是连续的吗
    • Python 3 教程
      Python 3 教程 Python 的 3.0 版本,常被称为 Python 3000,或简称 Py3k。相对于 Python 的早期版本,这是一个较大的升级。为了不带入过多的累赘,Python 3.0 在设计的时候没有考虑向下兼容。 Python
      Python 3 教程
    • Python pip包管理
      一、前言    在Python中, 安装第三方模块是通过 setuptools 这个工具完成的。 Python有两个封装了 setuptools的包管理工具: easy_install  和  pip , 目前官方推荐使用 pip。    
      Python pip包管理
    • ubuntu如何重新编译内核
    • 改善Java代码之慎用java动态编译

    目录