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 $.each的用法说明
Mar 22 Javascript
获取焦点时,利用js定时器设定时间执行动作
Apr 02 Javascript
Javascript 实用小技巧
Apr 07 Javascript
js getElementsByTagName的简写方式
Jun 27 Javascript
动态显示可输入的字数提示还可以输入的字数
Apr 01 Javascript
移动Web中图片自适应的两种JavaScript解决方法
Jun 18 Javascript
JavaScript仿商城实现图片广告轮播实例代码
Feb 06 Javascript
原生javascript实现addClass,removeClass,hasClass函数
Feb 25 Javascript
vue2.0 父组件给子组件传递数据的方法
Jan 15 Javascript
vue文件运行的方法教学
Feb 12 Javascript
使用异步组件优化Vue应用程序的性能
Apr 28 Javascript
微信小程序wxml列表渲染原理解析
Nov 27 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写的AES加密解密类分享
2014/06/20 PHP
PHP6连接SQLServer2005的三部曲
2016/04/15 PHP
thinkphp3.x中display方法及show方法的用法实例
2016/05/19 PHP
php 防止表单重复提交两种实现方法
2016/11/03 PHP
PHP如何使用JWT做Api接口身份认证的实现
2020/02/03 PHP
jquery slibings选取同级其他元素的实现代码
2013/11/15 Javascript
Jquery Uploadify上传带进度条的简单实例
2014/02/12 Javascript
javascript的事件触发器介绍的实现
2014/06/05 Javascript
jQuery UI插件实现百度提词器效果
2016/11/21 Javascript
jQuery按需加载轮播图(web前端性能优化)
2017/02/17 Javascript
js省市区级联查询(插件版&amp;无插件版)
2017/03/21 Javascript
Three.js实现浏览器变动时进行自适应的方法
2017/09/26 Javascript
Vue 兄弟组件通信的方法(不使用Vuex)
2017/10/26 Javascript
Vue结合路由配置递归实现菜单栏功能
2020/06/16 Javascript
详解vue-cli项目在IE浏览器打开报错解决方法
2020/12/10 Vue.js
利用Python中SocketServer 实现客户端与服务器间非阻塞通信
2016/12/15 Python
Pycharm学习教程(4) Python解释器的相关配置
2017/05/03 Python
Python对列表去重的多种方法(四种方法)
2017/12/05 Python
Python判断变量名是否合法的方法示例
2019/01/28 Python
Django 响应数据response的返回源码详解
2019/08/06 Python
Python流程控制 if else实现解析
2019/09/02 Python
浅谈django channels 路由误导
2020/05/28 Python
浅谈CSS3 动画卡顿解决方案
2019/01/02 HTML / CSS
html svg生成环形进度条的实现方法
2019/09/23 HTML / CSS
英国领先的运动营养品牌:Protein Dynamix
2018/01/02 全球购物
安德玛加拿大官网:Under Armour加拿大
2019/10/02 全球购物
《金孔雀轻轻跳》教学反思
2014/04/20 职场文书
服务标语大全
2014/06/18 职场文书
学校党的群众路线教育实践活动总结报告
2014/07/03 职场文书
村主任群众路线个人对照检查材料
2014/09/26 职场文书
交通事故赔偿协议书
2014/10/16 职场文书
诚信承诺书
2015/01/19 职场文书
感谢信模板大全
2015/01/23 职场文书
幼儿园教师管理制度
2015/08/05 职场文书
高中生综合素质评价范文
2015/08/18 职场文书
创业计划书之网吧
2019/10/10 职场文书