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中load方法的用法及注意事项说明
Feb 22 Javascript
jquery实现浮动的侧栏实例
Jun 25 Javascript
jQuery左右滚动支持图片放大缩略图图片轮播代码分享
Aug 26 Javascript
学习JavaScript设计模式(策略模式)
Nov 26 Javascript
javascript高级编程之函数表达式 递归和闭包函数
Nov 29 Javascript
前端学习笔记style,currentStyle,getComputedStyle的用法与区别
May 28 Javascript
JavaScript模块模式实例详解
Oct 25 Javascript
关闭Vue计算属性自带的缓存功能方法
Mar 02 Javascript
解决vuex刷新状态初始化的方法实现
Aug 15 Javascript
js 下拉菜单点击旁边收起实现(踩坑记)
Sep 29 Javascript
JS eval代码快速解密实例解析
Apr 23 Javascript
ES6 十大特性简介
Dec 09 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
非常不错的MySQL优化的8条经验
2008/03/24 PHP
php单例模式示例分享
2015/02/12 PHP
PHP判断JSON对象是否存在的方法(推荐)
2016/07/06 PHP
thinkphp5.0自定义验证规则使用方法
2017/11/16 PHP
创建一个复制UBB软件信息的链接或按钮的js代码
2008/01/06 Javascript
通过javascript设置css属性的代码
2009/12/28 Javascript
js 数值项目的格式化函数代码
2010/05/14 Javascript
让浏览器非阻塞加载javascript的几种方法小结
2011/04/25 Javascript
javascript模拟select,jselect的方法实现
2012/11/08 Javascript
浏览器的JavaScript引擎的识别方法
2013/10/20 Javascript
改变文件域的样式实现思路同时兼容ie、firefox
2013/10/23 Javascript
javascript数组操作方法小结和3个属性详细介绍
2014/07/05 Javascript
常用的JavaScript WEB操作方法分享
2015/02/28 Javascript
JavaScript中的对象与JSON
2015/07/03 Javascript
jQuery+CSS3折叠卡片式下拉列表框实现效果
2015/11/02 Javascript
Jquery on方法绑定事件后执行多次的解决方法
2016/06/02 Javascript
JavaScript用200行代码制作打飞机小游戏实例
2017/06/21 Javascript
nodejs实现的连接MySQL数据库功能示例
2018/01/25 NodeJs
vue.js系列中的vue-fontawesome使用
2018/02/10 Javascript
NodeJS搭建HTTP服务器的实现步骤
2018/10/12 NodeJs
JS 音频可视化插件Wavesurfer.js的使用教程
2018/10/31 Javascript
使用VueRouter的addRoutes方法实现动态添加用户的权限路由
2019/06/03 Javascript
[05:03]2018DOTA2亚洲邀请赛主赛事首日回顾
2018/04/04 DOTA
[54:57]DOTA2-DPC中国联赛定级赛 Aster vs DLG BO3第二场 1月8日
2021/03/11 DOTA
Python实现替换文件中指定内容的方法
2018/03/19 Python
Python简单实现两个任意字符串乘积的方法示例
2018/04/12 Python
如何修复使用 Python ORM 工具 SQLAlchemy 时的常见陷阱
2019/11/19 Python
python从内存地址上加载python对象过程详解
2020/01/08 Python
css3 图片圆形显示 如何CSS将正方形图片显示为圆形图片布局
2014/10/10 HTML / CSS
菲律宾旅游网站:Expedia菲律宾
2017/10/11 全球购物
DERMAdoctor官网:美国著名皮肤护理品牌
2019/07/06 全球购物
广告学专业应届生求职信
2013/10/01 职场文书
音乐系毕业生自荐信
2013/10/27 职场文书
大学生职业生涯规划书参考模板
2014/03/05 职场文书
求职信格式要求
2014/05/23 职场文书
python 中yaml文件用法大全
2021/07/04 Python