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

作者:daisy 时间:2024-04-19 10:16:44 

前言

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

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]);
}
};
})();

总结

标签:js,懒加载,插件
0
投稿

猜你喜欢

  • MySQL 备份还原数据库批处理

    2024-01-16 21:03:52
  • Go语言通道之无缓冲通道

    2024-04-25 15:25:57
  • 讲解MySQL中的事务特性

    2024-01-25 19:37:13
  • python 3调用百度OCR API实现剪贴板文字识别

    2022-12-13 19:01:14
  • Vue.js 中取得后台原生HTML字符串 原样显示问题的解决方法

    2024-04-30 10:21:38
  • JS实现拖动模糊框特效

    2023-08-06 05:18:51
  • 基于Python编写一个刷题练习系统

    2022-10-01 13:28:34
  • vue项目使用md5加密、crypto-js加密、国密sm3及国密sm4的方法

    2024-04-27 15:47:47
  • Oracle中大批量删除数据的方法

    2010-07-21 13:05:00
  • python脚本实现验证码识别

    2022-02-03 09:41:30
  • 基于tkinter中ttk控件的width-height设置方式

    2023-07-04 21:32:20
  • 选择python进行数据分析的理由和优势

    2022-03-31 10:51:01
  • 使用jQuery向asp.net Mvc传递复杂json数据-ModelBinder篇

    2024-06-05 09:32:20
  • Python中hash加密简介及使用方法

    2022-08-16 01:06:06
  • python DataFrame中loc与iloc取数据的基本方法实例

    2022-06-23 15:58:25
  • python给视频添加背景音乐并改变音量的具体方法

    2021-01-26 20:18:47
  • 为FCKeditor2.6添加行距功能(最新修改)

    2008-08-18 21:09:00
  • PHP mysql_result()函数使用方法

    2023-06-13 08:21:29
  • MySQL中slave_exec_mode参数详解

    2024-01-18 07:36:34
  • MySql用DATE_FORMAT截取DateTime字段的日期值

    2024-01-14 02:48:22
  • asp之家 网络编程 m.aspxhome.com