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 中文API Layout(Tabs)
Apr 27 Javascript
javaScript函数中执行C#代码中的函数方法总结
Aug 07 Javascript
js判断手机和pc端选择不同执行事件的方法
Jan 30 Javascript
JS实现字符串转日期并比较大小实例分析
Dec 09 Javascript
Three.js学习之几何形状
Aug 01 Javascript
Bootstrap框架结合jQuery仿百度换肤功能实例解析
Sep 17 Javascript
JavaScript数据结构链表知识详解
Nov 21 Javascript
js仿拉勾网首页穿墙广告效果
Mar 08 Javascript
AngularJS的脏检查深入分析
Apr 22 Javascript
JS实现运动缓冲效果的封装函数示例
Feb 18 Javascript
Vue.js实现双向数据绑定方法(表单自动赋值、表单自动取值)
Aug 27 Javascript
如何用vue实现网页截图你知道吗
Nov 17 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中的内存管理问题
2011/08/31 PHP
ThinkPHP3.1新特性之G方法的使用
2014/06/19 PHP
PHP高级编程实例:编写守护进程
2014/09/02 PHP
一波PHP中cURL库的常见用法代码示例
2016/05/06 PHP
LBS blog sql注射漏洞[All version]-官方已有补丁
2007/08/26 Javascript
原生Js实现按的数据源均分时间点幻灯片效果(已封装)
2010/12/28 Javascript
JQuery中使用on方法绑定hover事件实例
2014/12/09 Javascript
js Calender控件使用详解
2015/01/05 Javascript
javascript中call和apply的用法示例分析
2015/04/02 Javascript
jQuery简单注册和禁用全局事件的方法
2016/07/25 Javascript
vue组件实例解析
2017/01/10 Javascript
JS实现上传图片的三种方法并实现预览图片功能
2017/07/14 Javascript
详解Vue组件实现tips的总结
2017/11/01 Javascript
如何解决webpack-dev-server代理常切换问题
2019/01/09 Javascript
小程序最新获取用户昵称和头像的方法总结
2019/09/23 Javascript
如何在postman测试用例中实现断言过程解析
2020/07/09 Javascript
[04:01]2014DOTA2国际邀请赛 TITAN告别Ohaiyo期望明年再战
2014/07/15 DOTA
[00:42]《辉夜杯》—职业组预选赛12月3日15点 正式打响
2015/12/03 DOTA
python中的对象拷贝示例 python引用传递
2014/01/23 Python
Python中尝试多线程编程的一个简明例子
2015/04/07 Python
Python functools模块学习总结
2015/05/09 Python
python执行子进程实现进程间通信的方法
2015/06/02 Python
Python工程师面试题 与Python基础语法相关
2016/01/14 Python
python 实现网上商城,转账,存取款等功能的信用卡系统
2016/07/15 Python
对Python中内置异常层次结构详解
2018/10/18 Python
Python lambda表达式用法实例分析
2018/12/25 Python
Python常见数字运算操作实例小结
2019/03/22 Python
python flask搭建web应用教程
2019/11/19 Python
Python局部变量与全局变量区别原理解析
2020/07/14 Python
用python实现前向分词最大匹配算法的示例代码
2020/08/06 Python
奥地利度假券的专家:we-are.travel
2019/04/10 全球购物
戴尔新加坡官网:Dell Singapore
2020/12/13 全球购物
企业年度评优方案
2014/06/02 职场文书
2019暑假学生安全口号
2019/06/27 职场文书
了解Redis常见应用场景
2021/06/23 Redis
Python中22个万用公式的小结
2021/07/21 Python