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 相关文章推荐
js中匿名函数的N种写法
Sep 08 Javascript
javascript中window.event事件用法详解
Dec 11 Javascript
让ie6也支持websocket采用flash封装实现
Feb 18 Javascript
Javascript跨域请求的4种解决方式
Mar 17 Javascript
jquery时间下拉框小例子
Apr 15 Javascript
公共js在页面底部加载的注意事项介绍
Jul 18 Javascript
jquery实现二级导航下拉菜单效果
Dec 18 Javascript
JavaScript学习小结之被嫌弃的eval函数和with语句实例详解
Aug 01 Javascript
vuejs简单验证码功能完整示例
Jan 08 Javascript
vue实现表单录入小案例
Sep 27 Javascript
Postman无法正常返回结果问题解决
Aug 28 Javascript
【js设计模式】SOLID五大设计原则
Mar 24 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
Bo-Blog专用的给Windows服务器的IIS Rewrite程序
2007/08/26 PHP
php有效防止图片盗用、盗链的两种方法
2016/11/01 PHP
CI(CodeIgniter)框架实现图片上传的方法
2017/03/24 PHP
JAVASCRIPT对象及属性
2007/02/13 Javascript
js的alert弹出框出现乱码解决方案
2013/09/02 Javascript
jQuery使用CSS()方法给指定元素同时设置多个样式
2015/03/26 Javascript
jQuery插件EnPlaceholder实现输入框提示文字
2015/06/05 Javascript
jquery实现的动态回到顶部特效代码
2015/10/28 Javascript
JavaScript DOM 学习总结(五)
2015/11/24 Javascript
AngularJS用户选择器指令实例分析
2016/11/04 Javascript
jQuery 出现Cannot read property ‘msie’ of undefined错误的解决方法
2016/11/23 Javascript
详解JS中的attribute属性
2017/04/25 Javascript
nodejs实现OAuth2.0授权服务认证
2017/12/27 NodeJs
在vue中使用vuex,修改state的值示例
2019/11/08 Javascript
javascript中的offsetWidth、clientWidth、innerWidth及相关属性方法
2020/05/14 Javascript
[03:52]显微镜下的DOTA2第三期——英雄在无聊的时候干什么
2014/06/20 DOTA
python多线程编程中的join函数使用心得
2014/09/02 Python
Python实现删除Android工程中的冗余字符串
2015/01/19 Python
Django MEDIA的配置及用法详解
2019/07/25 Python
python同步两个文件夹下的内容
2019/08/29 Python
python:删除离群值操作(每一行为一类数据)
2020/06/08 Python
Python如何实现大型数组运算(使用NumPy)
2020/07/24 Python
美国高级工作服品牌:Carhartt
2018/01/25 全球购物
Nike澳大利亚官网:Nike.com (AU)
2019/06/03 全球购物
学校岗位设置方案
2014/01/16 职场文书
物理研修随笔感言
2014/02/14 职场文书
大学学风建设方案
2014/05/04 职场文书
社区优秀志愿者先进事迹
2014/05/09 职场文书
捐助贫困学生倡议书
2014/05/16 职场文书
2014副局长群众路线对照检查材料思想汇报
2014/09/22 职场文书
铁人纪念馆观后感
2015/06/16 职场文书
幼儿园开学家长寄语(2016春季)
2015/12/03 职场文书
Python Pandas pandas.read_sql函数实例用法
2021/06/21 Python
CSS实现两列布局的N种方法
2021/08/02 HTML / CSS
java多态注意项小结
2021/10/16 Java/Android
《遗弃》开发商删推文要跑路?官方回应:还在开发
2022/04/03 其他游戏