热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

一起来实现图片滚动懒加载

图片一直是网络资源占用大户,对于一个前端有几百张图片的网站来说,如果首屏即加载所有图片(无论这些图片有没有被用户看到)&#x

图片一直是网络资源占用大户,对于一个前端有几百张图片的网站来说,如果首屏即加载所有图片(无论这些图片有没有被用户看到),那无疑是既浪费网络资源,又伤害用户体验的事。因此,图片懒加载,是提高前端性能的刚需所在。

目前,淘宝网、知乎等大流量网站都已经使用了图片滚动懒加载的方案——仅当图片滚入视窗,被用户看到的时候,才会去真正加载。

基本原理

图片滚动懒加载的原理非常简单:基于标签,在初次加载时,不把图片url放在src属性中,而是自定义一个属性,例如data-src。然后检测"scroll","resize"等窗体事件,判断图片是否进入了可视范围。如果进入,则将data-src的字段替换到src,此时浏览器会自动去加载对应图片资源。

Talking is cheap, show you the code

首先是不添加src的img标签,新增data-src用于放置图片url:

<img class&#61;"lazyImg" data-src&#61;"http://xxx.xxx.com"/>

然后&#xff0c;我们需要新增一个数组队列&#xff0c;来储存所有未加载的img节点&#xff1a;

var lazyImg&#61;[].slice.call(document.querySelectorAll(".lazyImg"));

为了方便&#xff0c;这里直接用querySelectorAll来获取所有img节点。注意因为NodeList是只读数组&#xff0c;因此需要将其转化为数组&#xff0c;方便之后的增删。在真实环境中&#xff0c;还需给每个成员添加其最近的可滚动祖先节点的引用&#xff0c;即el.parentNode。

最关键的部分来了&#xff0c;如何判断图片是否进入了可视区域&#xff0c;以及实现加载呢&#xff1f;

// 参数传入lazyImg数组
function loadImage(images){let scrollParent,src,el;for(let i &#61; 0;i //img所属的最近的可滚动祖先节点el&#61;images[i].el;//offset为预留的预加载距离if(checkInView(el,scrollParent,this.options.offset)){src&#61;el.dataset.src;el.setAttribute("src",src);images.splice(i--,1); //将该img元素移除}}
}

上面提到的scrollParent是带有scroll特性的祖先节点&#xff0c;具体实现&#xff1a;可使用getComputedStyle检查父节点是否设置了overflow(overflow-x,overflow-y)为"auto"或"scroll"&#xff0c;不断循环直到找到满足条件的祖先节点。

下面封装了判断是否在可视区域的函数&#xff1a;

const checkInView&#61;(el,scrollParent,offset)&#61;>{let scrollTop,scrollLeft,clientH,clientW;if(scrollParent &#61;&#61;&#61; window) {scrollTop&#61;document.documentElement.scrollTop||document.body.scrollTop;scrollLeft&#61;document.documentElement.scrollLeft||document.body.scrollLeft;clientH&#61;document.documentElement.clientHeight||document.body.clientHeight;clientW&#61;document.documentElement.clientWidth||document.body.clientWidth;}else {scrollTop &#61; scrollParent.scrollTop;scrollLeft&#61;scrollParent.scrollLeft;clientH &#61; scrollParent.clientHeight;clientW&#61;scrollParent.clientWidth;}while(el!&#61;scrollParent && el!&#61;null){let borderWidth&#61;parseInt(getStyle(el,"border-width"));offsetTop&#43;&#61;el.offsetTop&#43;borderWidth;offsetLeft&#43;&#61;el.offsetLeft&#43;borderWidth;el&#61;el.offsetParent;}//在这里判断是否滚入可视区域。offset为预留的预加载距离if(scrollTop&#43;clientH>el.offsetTop-offset && scrollLeft&#43;clientW>el.offsetLeft-offset){return true;}else return false;
}

最后再让各自的scrollParent监听"scroll"&#xff0c;"resize"等事件即可&#xff1a;

function initListener(el){let scrollParent&#61;getScrollParent(el);if(this.scrollParent.indexOf(scrollParent)<0){position &#61; getStyle(scrollParent, "position"); //若为window则返回nullif (position&#61;&#61;&#61;"" || position &#61;&#61;&#61; "static") scrollParent.style.position &#61; "relative"; //确保能检测到正确的offsetTop和offsetLeftthis.scrollParent.push(scrollParent); //数组用于保存已经监听的可滚动祖先节点this.eventsList.forEach((event)&#61;>{scrollParent.addEventListener(event,this.loadImage.bind(this));})}
}

以上便是实现图片懒加载的关键代码。

如果有动态添加的img标签&#xff0c;该怎么办呢&#xff1f;其实很简单&#xff0c;只需要将新增的img元素push进这个lazyImg数组队列中&#xff0c;然后调用InitListener即可。

完整实现

利用以上原理&#xff0c;我实现了一个基于vue2.x的图片懒加载的插件&#xff0c;完整代码可参考这里vue-lazyload-images。

转:https://juejin.im/post/58e454ddb123db15eb79369a



推荐阅读
  • 个人学习使用:谨慎参考1Client类importcom.thoughtworks.gauge.Step;importcom.thoughtworks.gauge.T ... [详细]
  • 微软头条实习生分享深度学习自学指南
    本文介绍了一位微软头条实习生自学深度学习的经验分享,包括学习资源推荐、重要基础知识的学习要点等。作者强调了学好Python和数学基础的重要性,并提供了一些建议。 ... [详细]
  • 本文分享了一个关于在C#中使用异步代码的问题,作者在控制台中运行时代码正常工作,但在Windows窗体中却无法正常工作。作者尝试搜索局域网上的主机,但在窗体中计数器没有减少。文章提供了相关的代码和解决思路。 ... [详细]
  • 如何使用Java获取服务器硬件信息和磁盘负载率
    本文介绍了使用Java编程语言获取服务器硬件信息和磁盘负载率的方法。首先在远程服务器上搭建一个支持服务端语言的HTTP服务,并获取服务器的磁盘信息,并将结果输出。然后在本地使用JS编写一个AJAX脚本,远程请求服务端的程序,得到结果并展示给用户。其中还介绍了如何提取硬盘序列号的方法。 ... [详细]
  • Java容器中的compareto方法排序原理解析
    本文从源码解析Java容器中的compareto方法的排序原理,讲解了在使用数组存储数据时的限制以及存储效率的问题。同时提到了Redis的五大数据结构和list、set等知识点,回忆了作者大学时代的Java学习经历。文章以作者做的思维导图作为目录,展示了整个讲解过程。 ... [详细]
  • 本文讨论了一个关于cuowu类的问题,作者在使用cuowu类时遇到了错误提示和使用AdjustmentListener的问题。文章提供了16个解决方案,并给出了两个可能导致错误的原因。 ... [详细]
  • 计算机存储系统的层次结构及其优势
    本文介绍了计算机存储系统的层次结构,包括高速缓存、主存储器和辅助存储器三个层次。通过分层存储数据可以提高程序的执行效率。计算机存储系统的层次结构将各种不同存储容量、存取速度和价格的存储器有机组合成整体,形成可寻址存储空间比主存储器空间大得多的存储整体。由于辅助存储器容量大、价格低,使得整体存储系统的平均价格降低。同时,高速缓存的存取速度可以和CPU的工作速度相匹配,进一步提高程序执行效率。 ... [详细]
  • 关键词:Golang, Cookie, 跟踪位置, net/http/cookiejar, package main, golang.org/x/net/publicsuffix, io/ioutil, log, net/http, net/http/cookiejar ... [详细]
  • 本文探讨了C语言中指针的应用与价值,指针在C语言中具有灵活性和可变性,通过指针可以操作系统内存和控制外部I/O端口。文章介绍了指针变量和指针的指向变量的含义和用法,以及判断变量数据类型和指向变量或成员变量的类型的方法。还讨论了指针访问数组元素和下标法数组元素的等价关系,以及指针作为函数参数可以改变主调函数变量的值的特点。此外,文章还提到了指针在动态存储分配、链表创建和相关操作中的应用,以及类成员指针与外部变量的区分方法。通过本文的阐述,读者可以更好地理解和应用C语言中的指针。 ... [详细]
  • PHP图片截取方法及应用实例
    本文介绍了使用PHP动态切割JPEG图片的方法,并提供了应用实例,包括截取视频图、提取文章内容中的图片地址、裁切图片等问题。详细介绍了相关的PHP函数和参数的使用,以及图片切割的具体步骤。同时,还提供了一些注意事项和优化建议。通过本文的学习,读者可以掌握PHP图片截取的技巧,实现自己的需求。 ... [详细]
  • 目录实现效果:实现环境实现方法一:基本思路主要代码JavaScript代码总结方法二主要代码总结方法三基本思路主要代码JavaScriptHTML总结实 ... [详细]
  • javascript  – 概述在Firefox上无法正常工作
    我试图提出一些自定义大纲,以达到一些Web可访问性建议.但我不能用Firefox制作.这就是它在Chrome上的外观:而那个图标实际上是一个锚点.在Firefox上,它只概述了整个 ... [详细]
  • Python正则表达式学习记录及常用方法
    本文记录了学习Python正则表达式的过程,介绍了re模块的常用方法re.search,并解释了rawstring的作用。正则表达式是一种方便检查字符串匹配模式的工具,通过本文的学习可以掌握Python中使用正则表达式的基本方法。 ... [详细]
  • 从零学Java(10)之方法详解,喷打野你真的没我6!
    本文介绍了从零学Java系列中的第10篇文章,详解了Java中的方法。同时讨论了打野过程中喷打野的影响,以及金色打野刀对经济的增加和线上队友经济的影响。指出喷打野会导致线上经济的消减和影响队伍的团结。 ... [详细]
  • 本文介绍了在Vue项目中如何结合Element UI解决连续上传多张图片及图片编辑的问题。作者强调了在编码前要明确需求和所需要的结果,并详细描述了自己的代码实现过程。 ... [详细]
author-avatar
荣媛厉4
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有