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 国际象棋棋盘 实现代码
Jun 26 Javascript
Cookie 小记
Apr 01 Javascript
JavaScript关于提高网站性能的几点建议(一)
Jul 24 Javascript
JavaScript中获取时间的函数集
Aug 16 Javascript
教你用十行node.js代码读取docx的文本
Mar 08 Javascript
详解如何让InstantClick兼容MathJax、百度统计等
Sep 12 Javascript
js实现数组内数据的上移和下移的实例
Nov 14 Javascript
jquery自定义显示消息数量
Dec 19 jQuery
轻松解决JavaScript定时器越走越快的问题
May 13 Javascript
layui+jquery支持IE8的表格分页方法
Sep 28 jQuery
Element-ui树形控件el-tree自定义增删改和局部刷新及懒加载操作
Aug 31 Javascript
Selenium执行JavaScript脚本的方法示例
Dec 31 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 smarty的预保留变量总结
2008/12/04 PHP
php数组函数序列之array_unique() - 去除数组中重复的元素值
2011/10/29 PHP
php设计模式之职责链模式定义与用法经典示例
2019/09/19 PHP
MSN消息提示类
2006/09/05 Javascript
javascript 冒泡排序 正序和倒序实现代码
2010/12/14 Javascript
关于javascript function对象那些迷惑分析
2011/10/24 Javascript
基于jquery的鼠标拖动效果代码
2012/05/30 Javascript
jquery选择器之层级过滤选择器详解
2014/01/27 Javascript
键盘上一张下一张兼容IE/google/firefox等浏览器
2014/01/28 Javascript
浅析JavaScript基本类型与引用类型
2014/05/28 Javascript
DeviceOne 让你一见钟情的App快速开发平台
2016/02/17 Javascript
JS for循环中i++ 和 ++i的区别介绍
2016/07/20 Javascript
浅谈JavaScript 中有关时间对象的方法
2016/08/15 Javascript
jQuery实现获取元素索引值index的方法
2016/09/18 Javascript
Canvas实现动态的雪花效果
2017/02/13 Javascript
Vue.js render方法使用详解
2017/04/05 Javascript
package.json文件配置详解
2017/06/15 Javascript
vue+Element-ui实现分页效果实例代码详解
2018/12/10 Javascript
微信小程序授权登录解决方案的代码实例(含未通过授权解决方案)
2019/05/10 Javascript
[03:35]2018年度DOTA2最佳辅助位选手5号位-完美盛典
2018/12/17 DOTA
在Gnumeric下使用Python脚本操作表格的教程
2015/04/14 Python
python re正则匹配网页中图片url地址的方法
2018/12/20 Python
深入了解Python iter() 方法的用法
2019/07/11 Python
Python3enumrate和range对比及示例详解
2019/07/13 Python
西班牙三叶草药房:Farmacias Trébol
2019/05/03 全球购物
如何进行Linux分区优化
2016/09/13 面试题
工作自我评价怎么写
2014/01/29 职场文书
推广普通话标语
2014/06/27 职场文书
2014年医生工作总结
2014/11/21 职场文书
地震慰问信
2015/02/14 职场文书
全国爱眼日活动总结
2015/02/27 职场文书
2015年七一建党节演讲稿
2015/03/19 职场文书
2015年党员创先争优公开承诺书
2015/04/27 职场文书
入党后的感想
2015/08/10 职场文书
2016年党员公开承诺书格式范文
2016/03/24 职场文书
Golang 遍历二叉树
2022/04/19 Golang