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 EasyUI NumberBox(数字框)的用法
Jul 08 Javascript
js仿百度有啊通栏展示效果实现代码
May 28 Javascript
Seajs 简易文档 提供简单、极致的模块化开发体验
Apr 13 Javascript
用js实现放大镜的效果的简单实例
May 23 Javascript
Bootstrap组件系列之福利篇几款好用的组件(推荐)
Jun 23 Javascript
解决URL地址中的中文乱码问题的办法
Feb 10 Javascript
js获取指定时间的前几秒
Apr 05 Javascript
vue组件中的样式属性scoped实例详解
Oct 30 Javascript
vue调试工具vue-devtools安装及使用方法
Nov 07 Javascript
JQuery使用属性addClass、removeClass和toggleClass实现增加和删除类操作示例
Nov 18 jQuery
微信小程序利用for循环解决内容变更问题
Mar 05 Javascript
vue+elementui 实现新增和修改共用一个弹框的完整代码
Jun 08 Vue.js
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写MySQL数据 实现代码
2009/06/15 PHP
Linux(CentOS)下PHP扩展PDO编译安装的方法
2016/04/07 PHP
弹出模态框modal的实现方法及实例
2017/09/19 PHP
PHP有序表查找之二分查找(折半查找)算法示例
2018/02/09 PHP
event.currentTarget与event.target的区别介绍
2012/12/31 Javascript
GRID拖拽行的实例代码
2013/07/18 Javascript
DOM节点的替换或修改函数replaceChild()用法实例
2015/01/12 Javascript
JSON格式的键盘编码对照表
2015/01/29 Javascript
js+HTML5实现视频截图的方法
2015/06/16 Javascript
Jquery ajax 同步阻塞引起的UI线程阻塞问题
2015/11/17 Javascript
JavaScript动态创建div等元素实例讲解
2016/01/06 Javascript
JavaScript设计模式之策略模式详解
2017/06/09 Javascript
vue.extend与vue.component的区别和联系
2018/09/19 Javascript
详解JavaScript中的坐标和距离
2019/05/27 Javascript
LayUI数据接口返回实体封装的例子
2019/09/12 Javascript
详解如何在Vue项目中发送jsonp请求
2019/10/25 Javascript
JS实现动态无缝轮播
2020/01/11 Javascript
关于引入vue.js 文件的知识点总结
2020/01/28 Javascript
jQuery--遍历操作实例小结【后代、同胞及过滤】
2020/05/22 jQuery
在vue-cli3.0 中使用预处理器 (Sass/Less/Stylus) 配置全局变量操作
2020/08/10 Javascript
解决IDEA 的 plugins 搜不到任何的插件问题
2020/05/04 Python
Python绘图实现台风路径可视化代码实例
2020/10/23 Python
python3 re返回形式总结
2020/11/20 Python
html5适合移动应用开发的12大特性
2014/03/19 HTML / CSS
Html5中localStorage存储JSON数据并读取JSON数据的实现方法
2017/02/13 HTML / CSS
美国棒球装备和用品商店:Baseball Savings
2018/06/09 全球购物
公积金转移接收函
2014/01/11 职场文书
小学生获奖感言范文
2014/02/02 职场文书
员工试用期考核自我鉴定
2014/04/13 职场文书
体育课外活动总结
2014/07/08 职场文书
会计试用期自我评价
2014/09/19 职场文书
销售人才自我评价范文
2014/09/27 职场文书
幼儿教师师德师风自我剖析材料
2014/09/29 职场文书
党员个人总结自评
2015/02/14 职场文书
酒店厨房管理制度
2015/08/06 职场文书
springboot拦截器无法注入redisTemplate的解决方法
2021/06/27 Java/Android