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 相关文章推荐
Javascript 面向对象 命名空间
May 13 Javascript
鼠标左键单击冲突的问题解决方法(防止冒泡)
May 14 Javascript
ES6中如何使用Set和WeakSet
Mar 10 Javascript
URL的参数中有加号传值变为空格的问题(URL特殊字符)
Nov 04 Javascript
WebPack基础知识详解
Jan 16 Javascript
扩展bootstrap的modal模态框-动态添加modal框-弹出多个modal框
Feb 21 Javascript
Bootstrap显示与隐藏简单实现代码
Mar 06 Javascript
jQuery插件HighCharts绘制的2D堆柱状图效果示例【附demo源码下载】
Mar 14 Javascript
vue2.0 与 bootstrap datetimepicker的结合使用实例
May 22 Javascript
vue-router配合ElementUI实现导航的实例
Feb 11 Javascript
vue 权限认证token的实现方法
Jul 17 Javascript
javascript中layim之查找好友查找群组
Feb 06 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中通过ADO调用Asscess数据库和COM程序
2006/10/09 PHP
探讨:parse url解析URL,返回其组成部分
2013/06/14 PHP
如何取得中文字符串中出现次数最多的子串
2013/08/08 PHP
PHP中判断变量为空的几种方法小结
2013/11/12 PHP
Smarty模板学习笔记之Smarty简介
2014/05/20 PHP
php实现比较两个字符串日期大小的方法
2015/05/12 PHP
CodeIgniter中使用Smarty3基本配置
2015/06/29 PHP
JavaScript 对象成员的可见性说明
2009/10/16 Javascript
javascript下判断一个对象是否具有指定名称的属性的的代码
2010/01/11 Javascript
js获取html页面节点方法(递归方式)
2013/12/13 Javascript
JavaScript中${pageContext.request.contextPath}取值问题及解决方案
2016/12/08 Javascript
ionic cordova一次上传多张图片(类似input file提交表单)的实现方法
2016/12/16 Javascript
Jquery树插件zTree实现菜单树
2017/01/24 Javascript
基于vue.js实现侧边菜单栏
2017/03/20 Javascript
js轮播图透明度切换(带上下页和底部圆点切换)
2017/04/27 Javascript
IScroll那些事_当内容不足时下拉刷新的解决方法
2017/07/18 Javascript
JavaScript你不知道的一些数组方法
2017/08/18 Javascript
详解.vue文件中监听input输入事件(oninput)
2017/09/19 Javascript
Bootstrap实现翻页效果
2017/11/27 Javascript
vue实现文章内容过长点击阅读全文功能的实例
2017/12/28 Javascript
使用JQuery自动完成插件Auto Complete详解
2019/06/18 jQuery
Vue 组件的挂载与父子组件的传值实例
2020/09/02 Javascript
Vue 使用iframe引用html页面实现vue和html页面方法的调用操作
2020/11/16 Javascript
JavaScript中Object、map、weakmap的区别分析
2020/12/15 Javascript
[02:05]2014DOTA2西雅图邀请赛 老队长全明星大猜想谁不服就按进显示器
2014/07/08 DOTA
Python实现的旋转数组功能算法示例
2019/02/23 Python
Django Aggregation聚合使用方法解析
2019/08/01 Python
Django多数据库配置及逆向生成model教程
2020/03/28 Python
Css3圆角边框制作代码
2015/11/18 HTML / CSS
css3 column实现卡片瀑布流布局的示例代码
2018/06/22 HTML / CSS
丝芙兰法国官网:SEPHORA法国
2016/09/01 全球购物
Gloeilampgoedkoop荷兰:在线购买灯泡
2019/02/16 全球购物
药店主任岗位责任制
2014/02/10 职场文书
医学生就业推荐表自我鉴定
2014/03/26 职场文书
火箭队口号
2014/06/18 职场文书
vue里使用create, mounted调用方法
2022/04/26 Vue.js