js图片延迟加载(Lazyload)三种实现方式


Posted in Javascript onMarch 01, 2017

延迟加载也称为惰性加载,即在长网页中延迟加载图像。

用户滚动到它们之前,视口外的图像不会加载。

这与图像预加载相反,在长网页上使用延迟加载将使网页加载更快。

在某些情况下,它还可以帮助减少服务器负载。

延迟加载的优点:

提升用户的体验,如果图片数量较大,打开页面的时候要将将页面上所有的图片全部获取加载,很可能会出现卡顿现象,影响用户体验。因此,有选择性地请求图片,这样能明显减少了服务器的压力和流量,也能够减小浏览器的负担。

方法一

将页面上所有图片的src属性设置为loading.gif,而图片的真实路径则设置在data-src属性中。

当页面滚动的时候计算图片位置和滚动的位置,当图片出现在浏览器视口内时,将图片的src属性设置为data-src的值。

<img src="loading.png" data-src="image.png">
img { display: block; margin-bottom: 50px; }
function lazyload() {
 var images = document.getElementsByTagName('img');
 var n = 0; // 用于存储图片加载到的位置,避免每次都从第一张图片开始遍历 
 return function() {
 var seeHeight = document.documentElement.clientHeight;
 var scrollTop = document.documentElement.scrollTop || document.body.scrollTop;
 for(var i = n; i < images.length; i++) {
  if (images[i].offsetTop < seeHeight + scrollTop) {
  if (images[i].getAttribute('src') === 'loading.png') {
   images[i].src = images[i].getAttribute('data-src');
  }
  n = n + 1;
  }
 }
 }
}
lazyload(); //初始化首页的页面图片
window.addEventListener('scroll', lazyload(), false);

方法二

上面的方法虽然没什么问题,但是性能较差,因为当页面滚动时,scroll事件会高频触发,这非常影响浏览器性能。
所以,这里要对lazyload函数进行函数节流(throttle)与函数去抖(debounce)处理。

这里html和css代码不变,经过throttle处理的js代码如下:

function throttle (fn, delay, atleast) {
 var timeout = null,
  startTime = new Date();
 return function () {
 var curTime = new Date();
 clearTimeout(timeout);
 if (curTime - startTime >= atleast) {
  fn ();
  startTime = curTime;
 } else {
  timeout = setTimeout (fn, delay);
 }
 }
}

function lazyload() {
 var images = document.getElementsByTagName('img'),
  n = 0;  //存储图片加载到的位置,避免每次都从第一张图片开始遍历 
 return function() {
 var seeHeight = document.documentElement.clientHeight;
 var scrollTop = document.documentElement.scrollTop || document.body.scrollTop;
 for(var i = n; i < images.length; i++) {
  if(images[i].offsetTop < seeHeight + scrollTop) {
  if(images[i].getAttribute('src') === 'loading.png') {
   images[i].src = images[i].getAttribute('data-src');
  }
  n = n + 1;
  }
 }
 }
}
lazyload(); //初始化首页的页面图片
window.addEventListener('scroll', throttle(lazyload(), 500, 1000), false);

方法三

目前有一个新的 IntersectionObserver API,可以自动"观察"元素是否可见。

用这种方法实现代码非常简洁,但是许多浏览器不支持。

js图片延迟加载(Lazyload)三种实现方式

  • IntersectionObserver 传入一个回调函数,当其观察到元素集合出现时候,则会执行该函数。
  • io.observe 即要观察的元素,要一个个添加才可以。
  • io 管理的是一个数组,当元素出现或消失的时候,数组添加或删除该元素,并且执行该回调函数。
function query(selector) {
 return Array.from(document.querySelectorAll(selector));
}
var io = new IntersectionObserver(function(items) {
 items.forEach(function(item) {
 var target = item.target;
 if(target.getAttribute('src') == 'loading.png') {
  target.src = target.getAttribute('data-src');
 }
 })
});
query('img').forEach(function(item) {
 io.observe(item);

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
获取3个数组不重复的值的具体实现
Dec 30 Javascript
Jquery实现地铁线路指示灯提示牌效果的方法
Mar 02 Javascript
javascript原型模式用法实例详解
Jun 04 Javascript
Jquery跨浏览器文本复制插件Zero Clipboard的使用方法
Feb 28 Javascript
JavaScript 数组some()和filter()的用法及区别
May 20 Javascript
jquery实现文本框的禁用和启用
Dec 07 Javascript
实现点击下箭头变上箭头来回切换的两种方法【推荐】
Dec 14 Javascript
简单实现node.js图片上传
Dec 18 Javascript
自学实现angularjs依赖注入
Dec 20 Javascript
Angular2管道Pipe及自定义管道格式数据用法实例分析
Nov 29 Javascript
详解vue项目打包后通过百度的BAE发布到网上的流程
Mar 05 Javascript
JavaScript, select标签元素左右移动功能实现
May 14 Javascript
node.js实现回调的方法示例
Mar 01 #Javascript
JQ中$(window).load和$(document).ready区别与执行顺序
Mar 01 #Javascript
Angular2库初探
Mar 01 #Javascript
浅谈angular2的http请求返回结果的subcribe注意事项
Mar 01 #Javascript
JavaScript两个变量交换值的实现方法
Mar 01 #Javascript
js实现仿购物车加减效果
Mar 01 #Javascript
浅谈js中startsWith 函数不能在任何浏览器兼容的问题
Mar 01 #Javascript
You might like
PHP XML操作类DOMDocument
2009/12/16 PHP
php集成动态口令认证
2016/07/21 PHP
PHP递归的三种常用方式
2019/02/28 PHP
JavaScript入门教程(9) Document文档对象
2009/01/31 Javascript
利用JQuery为搜索栏增加tag提示
2009/06/22 Javascript
js arguments对象应用介绍
2012/11/28 Javascript
Js-$.extend扩展方法使方法参数更灵活
2013/01/15 Javascript
javascript使用location.search的示例
2013/11/05 Javascript
给事件响应函数传参数的四种方式小结
2013/12/05 Javascript
使用js判断当前时区TimeZone是否是夏令时
2014/02/23 Javascript
Node调试工具JSHint的安装及配置教程
2014/05/27 Javascript
js实现文本框支持加减运算的方法
2015/08/19 Javascript
实现非常简单的js双向数据绑定
2015/11/06 Javascript
基于JavaScript实现通用tab选项卡(通用性强)
2016/01/07 Javascript
jQuery 移动端artEditor富文本编辑器
2016/01/11 Javascript
如何用JS判断两个数字的大小
2016/07/21 Javascript
jQuery如何解决IE输入框不能输入的问题
2016/10/08 Javascript
EditPlus中的正则表达式 实战(2)
2016/12/15 Javascript
vue.js开发实现全局调用的MessageBox组件实例代码
2017/11/22 Javascript
详解Vue源码之数据的代理访问
2018/12/11 Javascript
jquery图片预览插件实现方法详解
2019/07/18 jQuery
jQuery表单选择器用法详解
2019/08/22 jQuery
layer.open提交子页面的form和layedit文本编辑内容的方法
2019/09/27 Javascript
JS如何在不同平台实现多语言方式
2020/07/16 Javascript
ant design vue导航菜单与路由配置操作
2020/10/28 Javascript
使用TS来编写express服务器的方法步骤
2020/10/29 Javascript
Python 出现错误TypeError: ‘NoneType’ object is not iterable解决办法
2017/01/12 Python
对pandas数据判断是否为NaN值的方法详解
2018/11/06 Python
django的model操作汇整详解
2019/07/26 Python
python3实现将json对象存入Redis以及数据的导入导出
2020/07/16 Python
Melijoe美国官网:法国奢侈童装购物网站
2017/04/19 全球购物
给定一个时间点,希望得到其他时间点
2013/11/07 面试题
商场消防演习方案
2014/02/12 职场文书
谁动了我的奶酪读书笔记
2015/06/30 职场文书
Pytorch DataLoader shuffle验证方式
2021/06/02 Python
Redis基本数据类型List常用操作命令
2022/06/01 Redis