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 select的操作实现代码
May 06 Javascript
Jquery实现列表(隔行换色,全选,鼠标滑过当前行)效果实例
Jun 09 Javascript
jQuery多级手风琴菜单实例讲解
Oct 22 Javascript
jQuery实现form表单元素序列化为json对象的方法
Dec 09 Javascript
jQuery操作cookie
Aug 08 Javascript
JS html时钟制作代码分享
Mar 03 Javascript
分享Bootstrap简单表格、表单、登录页面
Aug 04 Javascript
Vue2.0实现将页面中表格数据导出excel的实例
Aug 09 Javascript
webpack4+react多页面架构的实现
Oct 25 Javascript
vue刷新页面时去闪烁提升用户体验效果的实现方法
Dec 10 Javascript
简单了解vue 插值表达式Mustache
Jul 22 Javascript
Vue如何将页面导出成PDF文件
Aug 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
thinkphp实现数组分页示例
2014/04/13 PHP
PHP 以POST方式提交XML、获取XML,解析XML详解及实例
2016/10/26 PHP
PHP+JQUERY操作JSON实例
2017/03/23 PHP
PHP文字转图片功能原理与实现方法分析
2017/08/31 PHP
PHP实现求连续子数组最大和问题2种解决方法
2017/12/26 PHP
php实现将数组或对象写入到文件的方法小结【三种方法】
2020/04/22 PHP
js更优雅的兼容
2010/08/12 Javascript
JavaScript 高级篇之函数 (四)
2012/04/07 Javascript
Bootstrap基本样式学习笔记之表单(3)
2016/12/07 Javascript
微信页面倒计时代码(解决safari不兼容date的问题)
2016/12/13 Javascript
AngularJS解决ng-if中的ng-model值无效的问题
2017/06/21 Javascript
jQuery实现带右侧索引功能的通讯录示例【附源码下载】
2018/04/17 jQuery
vue插件draggable实现拖拽移动图片顺序
2018/12/01 Javascript
使用jquery模拟a标签的click事件无法实现跳转的解决
2018/12/04 jQuery
vue实现多级菜单效果
2019/10/19 Javascript
解决vue 表格table列求和的问题
2019/11/06 Javascript
vue中的计算属性和侦听属性
2020/11/06 Javascript
[01:00:49]DOTA2-DPC中国联赛 正赛 Ehome vs iG BO3 第二场 1月31日
2021/03/11 DOTA
python reverse反转部分数组的实例
2018/12/13 Python
Python实现带参数的用户验证功能装饰器示例
2018/12/14 Python
python的移位操作实现详解
2019/08/21 Python
Django 实现外键去除自动添加的后缀‘_id’
2019/11/15 Python
Python用input输入列表的实例代码
2020/02/07 Python
Django 再谈一谈json序列化
2020/03/16 Python
详解Python中namedtuple的使用
2020/04/27 Python
浅谈TensorFlow之稀疏张量表示
2020/06/30 Python
纯CSS3大转盘抽奖示例代码(响应式、可配置)
2017/01/13 HTML / CSS
css3 仿写阿里云水纹效果的示例代码
2018/02/10 HTML / CSS
详解css3中 text-fill-color属性
2019/07/08 HTML / CSS
大学活动总结格式
2014/04/29 职场文书
伊琍体标语
2014/06/25 职场文书
向女朋友道歉的话
2015/01/20 职场文书
2015学校师德师风工作总结
2015/04/22 职场文书
Mysql Online DDL的使用详解
2021/05/20 MySQL
小程序与后端Java接口交互实现HelloWorld入门
2021/07/09 Java/Android
OpenCV实现反阈值二值化
2021/11/17 Java/Android