Javascript实现图片懒加载插件的方法


Posted in Javascript onOctober 20, 2016

前言

网络上各大论坛,尤其是一些图片类型的网站上,在图片加载时均采用了一种名为懒加载的方式,具体表现为,当页面被请求时,只加载可视区域的图片,其它部分的图片则不加载,只有这些图片出现在可视区域时才会动态加载这些图片,从而节约了网络带宽和提高了初次加载的速度,具体实现的技术并不复杂,下面分别对其说明。

Web 图片的懒加载就是通过读取img元素,然后获得img元素的data-src(也可以约定为其他属性名)属性的值,并赋予img的src,从而实现动态加载图片的机制。

这里需要注意的是: img在初始化的时候不要设置src属性,因为即使设置 src='' 浏览器也会尝试加载图片。

一个简单的图片懒加载共涉及两个方面

1. HTML 约定

我们首先需要给准备实施懒加载的img元素添加指定的class 这里为m-lazyload ,同时将img src赋值给 data-src属性。

具体示例为:

<img class="m-lazyload" data-src="imgUrl">

2. JavaScript 实现

动态加载总共分为以下几个步骤,这里每个步骤都将被拆分为独立的函数

1. 添加页面滚动监听事件

window.addEventListener('scroll', _delay, false);

function _delay() {
 clearTimeout(delay);
 delay = setTimeout(function () {
 _loadImage();
 }, time);
}

2. 当触发监听事件时会执行 _loadImage 函数,该函数负责加载图片

function _loadImage() {
 for (var i = imgList.length; i--;) {
 var el = imgList[i];
 if (_isShow(el)) {
  el.src = el.getAttribute('data-src');
  el.className = el.className.replace(new RegExp("(\\s|^)" + _selector.substring(1, _selector.length) + "(\\s|$)"), " ");
  imgList.splice(i, 1);
 }
 }
}

虽然执行了_loadImage函数,但是我们得知道哪些图片需要被加载,这里的判断依据是什么呢?

依据就是判断该图片是否在当前窗口的可视区域内,在这里我们封装一个_isShow函数来实现

function _isShow(el) {
 var coords = el.getBoundingClientRect();
 return ( (coords.top >= 0 && coords.left >= 0 && coords.top) <= (window.innerHeight || document.documentElement.clientHeight) + parseInt(offset));
}

自此一个图片加载的闭环就形成了

当网页滚动的事件被触发 -> 执行加载图片操作 -> 判断图片是否在可视区域内 -> 在,则动态将data-src的值赋予该图片。

太简单了?

事实就是如此!!!

如此简单,不妨扩展一下

添加一些自定义参数,谁都喜欢自定义,不是吗?

支持iScroll, iScroll是一个高性能,资源占用少,无依赖,多平台的javascript滚动插件。

这里我们做了些优化

图片加载后移除选择器,避免重复判断。

缓存img元素结合,减少dom元素查询性能损耗

扩展prototype添加getNode方法,支持分页数据懒加载(由于我们之前缓存了dom元素)

OK!说了这么多,show me the code 吧!

(function () {
 var imgList = [], // 页面所有img元素集合
 delay, // setTimeout 对象
 offset, //偏移量,用于指定图片距离可视区域多少距离,进行加载
 time, // 延迟载入时间
 _selector; // 选择器 默认为 .m-lazyload

 function _isShow(el) {
 var coords = el.getBoundingClientRect();
 return ( (coords.top >= 0 && coords.left >= 0 && coords.top) <= (window.innerHeight || document.documentElement.clientHeight) + parseInt(offset));
 }

 function _loadImage() {
 for (var i = imgList.length; i--;) {
  var el = imgList[i];
  if (_isShow(el)) {
  el.src = el.getAttribute('data-src');
  el.className = el.className.replace(new RegExp("(\\s|^)" + _selector.substring(1, _selector.length) + "(\\s|$)"), " ");
  imgList.splice(i, 1);
  }
 }
 }

 function _delay() {
 clearTimeout(delay);
 delay = setTimeout(function () {
  _loadImage();
 }, time);
 }

 function ImageLazyload(selector, options) {
 var defaults = options || {};
 offset = defaults.offset || 0;
 time = defaults.time || 250;
 _selector = selector || '.m-lazyload';
 this.getNode();
 _delay();//避免首次加载未触发touch事件,主动触发一次加载函数
 if (defaults.iScroll) {
  defaults.iScroll.on('scroll', _delay);
  defaults.iScroll.on('scrollEnd', _delay);
 } else {
  window.addEventListener('scroll', _delay, false);
 }
 }
 ImageLazyload.prototype.getNode = function () {
 imgList = [];
 var nodes = document.querySelectorAll(_selector);
 for (var i = 0, l = nodes.length; i < l; i++) {
  imgList.push(nodes[i]);
 }
 };
})();

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家学习或者使用图片懒加载的时候能有所帮助,如果有有疑问大家可以留言交流。

Javascript 相关文章推荐
js事件(Event)知识整理
Oct 11 Javascript
jQuery ui插件的使用方法代码实例
May 08 Javascript
JS的Document属性和方法小结
Sep 17 Javascript
jQuery实现Div拖动+键盘控制综合效果的方法
Mar 10 Javascript
javascript实现模拟时钟的方法
May 13 Javascript
Bootstrap源码解读导航条(7)
Dec 23 Javascript
jQuery布局组件EasyUI Layout使用方法详解
Feb 28 Javascript
JavaScript之浏览器对象_动力节点Java学院整理
Jul 03 Javascript
three.js实现3D影院的原理的代码分析
Dec 18 Javascript
通过fastclick源码分析彻底解决tap“点透”
Dec 24 Javascript
vue中如何实现pdf文件预览的方法
Jul 12 Javascript
Vue监听页面刷新和关闭功能
Jun 20 Javascript
Vue.js Ajax动态参数与列表显示实现方法
Oct 20 #Javascript
探究Vue.js 2.0新增的虚拟DOM
Oct 20 #Javascript
Javascript 创建类并动态添加属性及方法的简单实现
Oct 20 #Javascript
javascript匀速动画和缓冲动画详解
Oct 20 #Javascript
js设置和获取自定义属性的方法
Oct 20 #Javascript
js阻止冒泡和默认事件(默认行为)详解
Oct 20 #Javascript
浅谈JS中String()与 .toString()的区别
Oct 20 #Javascript
You might like
PHP 飞信好友免费短信API接口开源版
2010/07/22 PHP
php 5.3.5安装memcache注意事项小结
2011/04/12 PHP
PHP中使用glob函数实现一句话删除某个目录下的所有文件
2014/07/22 PHP
微信公众平台开发实现2048游戏的方法
2015/04/15 PHP
javascript 贪吃蛇实现代码
2008/11/22 Javascript
jQuery timers计时器简单应用说明
2010/10/28 Javascript
window.location.href的用法(动态输出跳转)
2014/08/09 Javascript
JavaScript设计模式之外观模式介绍
2014/12/28 Javascript
基于JavaScript实现本地图片预览
2017/02/08 Javascript
JS实现css hover操作的方法示例
2017/04/07 Javascript
详解nodejs express下使用redis管理session
2017/04/24 NodeJs
js微信分享实现代码
2020/10/11 Javascript
vue列表单项展开收缩功能之this.$refs的详解
2019/05/05 Javascript
如何用vue-cli3脚手架搭建一个基于ts的基础脚手架的方法
2019/12/12 Javascript
Vue项目中使用flow做类型检测的方法
2020/03/18 Javascript
JavaScript字符和ASCII实现互相转换
2020/06/03 Javascript
JavaScript实现复选框全选和取消全选
2020/11/20 Javascript
[34:08]2018DOTA2亚洲邀请赛3月29日 小组赛B组 VP VS EG
2018/03/30 DOTA
python中map、any、all函数用法分析
2015/04/21 Python
使用Python脚本生成随机IP的简单方法
2015/07/30 Python
使用Python3编写抓取网页和只抓网页图片的脚本
2015/08/20 Python
Python中装饰器高级用法详解
2017/12/25 Python
Python使用flask框架操作sqlite3的两种方式
2018/01/31 Python
django模板加载静态文件的方法步骤
2019/03/01 Python
Python 类的私有属性和私有方法实例分析
2019/09/29 Python
Python GUI自动化实现绕过验证码登录
2020/01/10 Python
英国家具、照明、家居用品网上商店:Wayfair.co.uk
2020/02/13 全球购物
六十大寿答谢词
2014/01/12 职场文书
学习十八大报告感言
2014/02/04 职场文书
yy婚礼主持词
2014/03/14 职场文书
宣传工作经验材料
2014/06/02 职场文书
音乐节策划方案
2014/06/09 职场文书
党政领导班子群众路线对照检查材料
2014/10/26 职场文书
骨干教师个人总结
2015/02/11 职场文书
MySql存储过程之逻辑判断和条件控制
2021/05/26 MySQL
Nginx如何配置多个服务域名解析共用80端口详解
2022/09/23 Servers