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实现后台左侧菜单点击上下滑动显示
Apr 11 Javascript
js动态添加事件并可传参数示例代码
Oct 21 Javascript
深入理解javascript严格模式(Strict Mode)
Nov 28 Javascript
JS封装cookie操作函数实例(设置、读取、删除)
Nov 17 Javascript
vuex实现简易计数器
Oct 27 Javascript
详解利用exif.js解决ios手机上传竖拍照片旋转90度问题
Nov 04 Javascript
AngularJS路由实现页面跳转实例
Mar 03 Javascript
详谈jQuery中使用attr(), prop(), val()获取value的异同
Apr 25 jQuery
JS实现table表格固定表头且表头随横向滚动而滚动
Oct 26 Javascript
angularjs 页面自适应高度的方法
Jan 17 Javascript
element ui 对话框el-dialog关闭事件详解
Feb 26 Javascript
微信小程序ibeacon三点定位详解
Oct 31 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
怎样在UNIX系统下安装MySQL
2006/10/09 PHP
《PHP编程最快明白》第五讲:php目录、文件操作
2010/11/01 PHP
那些年一起学习的PHP(三)
2012/03/22 PHP
百度ping方法使用示例 自动ping百度
2014/01/26 PHP
php实现每天自动变换随机问候语的方法
2015/05/12 PHP
关于锚点跳转及jQuery下相关操作与插件
2012/10/01 Javascript
JQuery 常用方法和事件详细介绍
2013/04/18 Javascript
单元选择合并变色示例代码
2014/05/26 Javascript
js实现多选项切换导航菜单的方法
2015/02/06 Javascript
c#程序员对TypeScript的认识过程
2015/06/19 Javascript
javascript电商网站抢购倒计时效果实现
2015/11/19 Javascript
详解JavaScript异步编程中jQuery的promise对象的作用
2016/05/03 Javascript
Jquery为DIV添加click事件的简单实例
2016/06/02 Javascript
详解nodejs 文本操作模块-fs模块(四)
2016/12/22 NodeJs
vue生成随机验证码的示例代码
2017/09/29 Javascript
bootstrap Table的一些小操作
2017/11/01 Javascript
深入Vue-Router路由嵌套理解
2018/08/13 Javascript
利用Vconsole和Fillder进行移动端抓包调试方法
2019/03/05 Javascript
深入了解JavaScript代码覆盖
2019/06/13 Javascript
bootstrap实现嵌套模态框的实例代码
2020/01/10 Javascript
vue实现微信浏览器左上角返回按钮拦截功能
2020/01/18 Javascript
Js数组扁平化实现方法代码总汇
2020/11/11 Javascript
js前端对于大量数据的展示方式及处理方法
2020/12/02 Javascript
Python实现的批量下载RFC文档
2015/03/10 Python
python optparse模块使用实例
2015/04/09 Python
Python中使用装饰器时需要注意的一些问题
2015/05/11 Python
python调用API接口实现登陆短信验证
2020/05/10 Python
解决pycharm debug时界面下方不出现step等按钮及变量值的问题
2020/06/09 Python
基于 HTML5 Canvas实现 的交互式地铁线路图
2018/03/05 HTML / CSS
毕业生文员求职信
2013/11/03 职场文书
经典优秀个人求职信分享
2013/12/12 职场文书
上班离岗检讨书
2014/01/27 职场文书
护理学专业求职信
2014/06/29 职场文书
创建绿色学校先进个人材料
2014/08/20 职场文书
2014年小学安全工作总结
2014/12/04 职场文书
党支部考察意见范文
2015/06/02 职场文书