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 相关文章推荐
彪哥1.1(智能表格)提供下载
Sep 07 Javascript
关于javascript event flow 的一个bug详解
Sep 17 Javascript
通过JS判断联网类型和连接状态的实现代码
Apr 01 Javascript
jQuery validate插件实现ajax验证重复的2种方法
Jan 22 Javascript
设置点击文本框或图片弹出日历控件的实现代码
May 12 Javascript
JS实现浏览器打印、打印预览示例
Feb 28 Javascript
vuejs绑定class和style样式
Apr 11 Javascript
arcgis for js栅格图层叠加(Raster Layer)问题
Nov 22 Javascript
Angular实现下拉框模糊查询功能示例
Jan 03 Javascript
实例介绍JavaScript中多种组合继承
Jan 20 Javascript
7个好用的JavaScript技巧分享(译)
May 07 Javascript
基于javascript实现贪吃蛇经典小游戏
Apr 10 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
php面向对象的方法重载两种版本比较
2008/09/08 PHP
PHP simple_html_dom.php+正则 采集文章代码
2009/12/24 PHP
关于PHP自动判断字符集并转码的详解
2013/06/26 PHP
PHP中fwrite与file_put_contents性能测试代码
2013/08/02 PHP
自己写的php中文截取函数mb_strlen和mb_substr
2015/02/09 PHP
PHP如何通过AJAX方式实现登录功能
2015/11/23 PHP
深入理解PHP JSON数组与对象
2016/07/19 PHP
PHP树形结构tree类用法示例
2019/02/01 PHP
使用javascript实现页面定时跳转总结篇
2013/09/21 Javascript
更快的异步执行(setTimeout多浏览器)
2014/08/12 Javascript
sails框架的学习指南
2014/12/22 Javascript
AngularJS中的$watch(),$digest()和$apply()区分
2016/04/04 Javascript
javascript特殊文本输入框网页特效
2016/09/13 Javascript
简单的jQuery拖拽排序效果的实现(增强动态)
2017/02/09 Javascript
vue父组件点击触发子组件事件的实例讲解
2018/02/08 Javascript
Vue.js项目中管理每个页面的头部标签的两种方法
2018/06/25 Javascript
VUE+Element UI实现简单的表格行内编辑效果的示例的代码
2018/10/31 Javascript
vuex 实现getter值赋值给vue组件里的data示例
2019/11/05 Javascript
Vue执行方法,方法获取data值,设置data值,方法传值操作
2020/08/05 Javascript
[05:00]TI9战队采访 - Royal Never Give Up
2019/08/20 DOTA
Python多进程机制实例详解
2015/07/02 Python
python腾讯语音合成实现过程解析
2019/08/01 Python
完美解决keras保存好的model不能成功加载问题
2020/06/11 Python
PyChon中关于Jekins的详细安装(推荐)
2020/12/28 Python
CSS3中伪元素::before和::after的用法示例
2017/09/18 HTML / CSS
凯伦·米莲女装网上商店:Karen Millen
2017/11/07 全球购物
多媒体编辑专业毕业生推荐信
2013/11/05 职场文书
有针对性的求职自荐信
2013/11/14 职场文书
手工社团活动方案
2014/02/17 职场文书
日语专业求职信
2014/07/04 职场文书
个人整改措施落实情况汇报
2014/10/29 职场文书
教师党员个人自我评价
2015/03/04 职场文书
2019教师的学习计划
2019/06/25 职场文书
创业计划书之青年旅馆
2019/09/23 职场文书
一行Python命令实现批量加水印
2022/04/07 Python
CSS使用Flex和Grid布局实现3D骰子
2022/08/05 HTML / CSS