JavaScript实现图片懒加载的方法分析


Posted in Javascript onJuly 05, 2018

本文实例讲述了JavaScript实现图片懒加载的方法。分享给大家供大家参考,具体如下:

懒加载是非常实用的提升网页性能的方式,当访问一个页面的时候,只显示可视区域内的图片,其它的图片只有出现在可视区域内的时候才会被请求加载。

我们现在用原生的js实现简单的图片懒加载,主要利用的原理就是先不给设置src,而是把图片的路径放在data-src中,等待图片被加载的时候将路径取出放到src中。

HTML代码

<div class="container">
 <div class="img-area">
  <img class="my-photo" alt="loading" data-src="img/img1.png">
 </div>
 <div class="img-area">
  <img class="my-photo" alt="loading" data-src="img/img2.png">
 </div>
 <div class="img-area">
  <img class="my-photo" alt="loading" data-src="img/img3.png">
 </div>
 <div class="img-area">
  <img class="my-photo" alt="loading" data-src="img/img4.png">
 </div>
 <div class="img-area">
  <img class="my-photo" alt="loading" data-src="img/img5.png">
 </div>
</div>

判断元素是否在可视区域

方法一:

1. 获取屏幕可视区高度:document.documentElement.clientHeight
2. 获取元素距顶部的高度:element.offsetTop
3. 获取滚动高度:document.documentElement.scrollTop
4. 若满足:2-3<1,那么元素就出现在可视区域

方法二:

1. 获取元素到可视区域顶部的距离:var bound = element.getBoundingClientRect()
2. 获取可视区域的高度:window.innerHeight
3. 若满足bound.top<=window.innerHeight,那么元素就出现在可视区域

方法三:

利用IntersectionObserver函数自动观察元素是否在可视区域内

var watch = new IntersectionObserver(callback,option);
//开始观察
watch.observe(el);
//停止观察
watch.unobserve(el);
//关闭观察器
watch.disconnect();

js代码

第一种很多人都用过,所以我们就用第二种写一下

//判断图片是否出现在可视区域内
function isInSight(el) {
    const bound = el.getBoundingClientRect();
    const clientHeight = window.innerHeight;
    return bound.top <= clientHeight + 100;
}
//加载图片
let index = 0;
function checkImgs() {
    const imgs = document.querySelectorAll('.my-photo');
    for( let i = index; i < imgs.length; i++){
      if(isInSight(imgs[i])){
        loadImg(imgs[i]);
        index = i;
      }
    }
}
function loadImg(el) {
    if(!el.src){
      const source = el.dataset.src;
      el.src = source;
    }
}
//函数节流
//函数节流是很重要的思想,可以防止过于频繁的操作dom
function throttle(fn,mustRun = 500) {
    const timer = null;
    let previous = null;
    return function () {
      const now = new Date();
      const context = this;
      const args = arguments;
      if(!previous){
        previous = now;
      }
      const remaining = now -previous;
      if(mustRun && remaining >= mustRun){
        fn.apply(context,args);
        previous = now;
      }
    }
  }
//调用函数
window.onload=checkImgs;
window.onscroll = throttle(checkImgs);

我们在用第三种方法写一个demo

function checkImgs() {
 const imgs = Array.from(document.querySelectorAll(".my-photo"));
 imgs.forEach(item => io.observe(item));
}
function loadImg(el) {
 if (!el.src) {
  const source = el.dataset.src;
  el.src = source;
 }
}
const io = new IntersectionObserver(ioes => {
 ioes.forEach(ioe => {
  const el = ioe.target;
  const intersectionRatio = ioe.intersectionRatio;
  if (intersectionRatio > 0 && intersectionRatio <= 1) {
   loadImg(el);
  }
  el.onload = el.onerror = () => io.unobserve(el);
 });
});

希望本文所述对大家JavaScript程序设计有所帮助。

Javascript 相关文章推荐
查看源码的工具 学习jQuery源码不错的工具
Dec 26 Javascript
ajax的hide隐藏问题解决方法
Dec 11 Javascript
100个不能错过的实用JS自定义函数
Mar 05 Javascript
JavaScript作用域示例详解
Jul 07 Javascript
jquery+ajax实现省市区三级联动效果简单示例
Jan 04 Javascript
详解angularjs 关于ui-router分层使用
Jun 12 Javascript
详解关于html,css,js三者的加载顺序问题
Apr 10 Javascript
详解如何理解vue的key属性
Apr 14 Javascript
vue 组件开发原理与实现方法详解
Nov 29 Javascript
解决vue.js中settimeout遇到的问题(时间参数短效果不稳定)
Jul 21 Javascript
vant-ui AddressEdit地址编辑和van-area的用法说明
Nov 03 Javascript
一篇文章弄清楚Ajax请求的五个步骤
Mar 17 Javascript
JavaScript实现浅拷贝与深拷贝的方法分析
Jul 05 #Javascript
手把手教你用Node.js爬虫爬取网站数据的方法
Jul 05 #Javascript
vue使用ElementUI时导航栏默认展开功能的实现
Jul 04 #Javascript
vue两个组件间值的传递或修改方式
Jul 04 #Javascript
jQuery实现炫丽的3d旋转星空效果
Jul 04 #jQuery
jQuery实现table表格checkbox全选的方法分析
Jul 04 #jQuery
React组件内事件传参实现tab切换的示例代码
Jul 04 #Javascript
You might like
php设计模式 Adapter(适配器模式)
2011/06/26 PHP
完美解决令人抓狂的zend studio 7代码提示(content Assist)速度慢的问题
2013/06/20 PHP
PHP伪静态Rewrite设置之APACHE篇
2014/07/30 PHP
PHP中new static() 和 new self() 的区别介绍
2015/01/09 PHP
php实现的RSS生成类实例
2015/04/23 PHP
php微信开发之上传临时素材
2016/06/24 PHP
PHP7.1方括号数组符号多值复制及指定键值赋值用法分析
2016/09/26 PHP
PHP调用微博接口实现微博登录的方法示例
2018/09/22 PHP
可兼容IE的获取及设置cookie的jquery.cookie函数方法
2013/09/02 Javascript
jquery Ajax 实现加载数据前动画效果的示例代码
2014/02/07 Javascript
常见浏览器多长时间会提示“脚本运行时间过长”总结
2014/04/29 Javascript
jQuery树形下拉菜单特效代码分享
2015/08/15 Javascript
vue.js实现条件渲染的实例代码
2017/06/22 Javascript
VUE axios上传图片到七牛的实例代码
2017/07/28 Javascript
史上最全JavaScript数组去重的十种方法(推荐)
2017/08/17 Javascript
vue-router实现组件间的跳转(参数传递)
2017/11/07 Javascript
jquery操作checkbox的常用方法总结【附测试源码下载】
2019/06/10 jQuery
vue elementUI使用tabs与导航栏联动
2019/06/21 Javascript
详解Vue后台管理系统开发日常总结(组件PageHeader)
2019/11/01 Javascript
js绘制一条直线并旋转45度
2020/08/21 Javascript
JS轮播图的实现方法2
2020/08/25 Javascript
javascript实现点击小图显示大图
2020/11/29 Javascript
[01:08:17]2018DOTA2亚洲邀请赛3月29日 小组赛B组 EG VS VGJ.T
2018/03/30 DOTA
二种python发送邮件实例讲解(python发邮件附件可以使用email模块实现)
2013/12/03 Python
使用Python脚本在Linux下实现部分Bash Shell的教程
2015/04/17 Python
python编写朴素贝叶斯用于文本分类
2017/12/21 Python
解决python多线程报错:AttributeError: Can't pickle local object问题
2020/04/08 Python
jupyter notebook oepncv 显示一张图像的实现
2020/04/24 Python
Django如何使用redis作为缓存
2020/05/21 Python
CSS3实现跳动的动画效果
2016/09/12 HTML / CSS
Java面试题及答案
2012/09/08 面试题
荷叶圆圆教学反思
2014/02/01 职场文书
反腐倡廉标语
2014/06/24 职场文书
法英专业大学生职业生涯规划范文:衡外情,量己力!
2014/09/23 职场文书
公安局班子个人对照检查材料思想汇报
2014/10/09 职场文书
安全生产先进个人总结
2015/02/15 职场文书