今天试用了下hello mui上的图片懒加载功能,发现有些地方还无法满足我的需求,ajax动态加载的时候无法实现懒加载。
然后又看了下36kr的示例,因为代码关系实在太多了,耦合度比较高,遂自己动手写了一个轻量级的懒加载功能模块,而且支持图片缓存到本地哦~~~
欢迎各位拍砖,交流碰撞思想!
升级日志
v1.1.0 build 20160107
1、已增加 @LFZ 的代码,不用重复下载两次服务器端的图片
2、新增图片加载淡入特效
3、新增图片加载完成后回调
4、修改data-src为data-lazyload
功能特性
~原生实现,不依赖任何前端框架
~ajax动态加载支持图片懒加载
~支持图片缓存到本地
~轻量模块化
如何使用
1、引入md5.min.js,因为依赖js版md5函数,用于将图片url转换为32位md5
<script s r c="md5.min.js"></script>
2、在头部js包含下面的lazyload方法函数,否则可能报错函数未定义
3、HTML代码使用ajax动态生成如下img标签,src为默认图片,data-src填写图片网络地址,并且必须包含onload事件来触发懒加载功能。
<img s r c="placehold.jpg" data-lazyload="http://...jpg" onload="lazyload(this)" />
注意:因为函数依赖plus.io和plus.downloader接口,所以在plus还没ready的时候img onload执行lazyload可能会报错,lazyload比plus先执行完毕。
当然,在真实环境中,不管是商品列表、订单列表等,我们的图片一般都是动态加载的,所以问题不大。
在代码的写法策略上需要使用动态加载方式,尽量不使用写死在html里面。
4、添加.img-lazyload 支持图片淡入样式
@-webkit-keyframes fadeIn{0%{opacity:0}100%{opacity:1}}
@keyframes fadeIn{0%{opacity:0}100%{opacity:1}}
.img-lazyload{-webkit-animation: fadeIn 350ms linear 0ms 1 normal both;animation: fadeIn 350ms linear 0ms 1 normal both;opacity:1;}
5、图片默认缓存到_downloads/image/目录下
活动图
函数源代码
/**
* 图片懒加载
* @param {Object} obj DOMElement
* @param {Function} callback 加载完成回调函数
*
* @author fanrong33
* @version 1.1.0 build 20160107
*/
function lazyload(obj, callback){
var debug = false; // 默认打印调试日志
if(obj.getAttribute('data-loaded')){
return;
}
var image_url = obj.getAttribute('data-lazyload');
debug && console.log(image_url);
// 1. 转换网络图片地址为本地缓存图片路径,判断该图片是否存在本地缓存
// http://...jpg -> md5
// 缓存目录 _downloads/image/(md5).jpg
var image_md5 = md5(image_url);
var local_image_url = '_downloads/image/'+image_md5+'.jpg'; // 缓存本地图片url
var absolute_image_path = plus.io.convertLocalFileSystemURL(local_image_url); // 平台绝对路径
// new temp_img 用于判断图片文件是否存在
var temp_img = new Image();
temp_img.src = absolute_image_path;
temp_img.onload = function(){
debug && console.log('存在本地缓存图片文件'+local_image_url+',直接显示');
// 1.1 存在,则直接显示(本地已缓存,不需要淡入动画)
obj.setAttribute('src', absolute_image_path);
obj.setAttribute('data-loaded', true);
obj.classList.add('img-lazyload');
callback && callback();
return;
}
temp_img.onerror = function(){
debug && console.log('不存在本地缓存图片文件');
// 1.2 下载图片缓存到本地
debug && console.log('开始下载图片'+image_url+' 缓存到本地: '+local_image_url);
function download_img(){
var download_task = plus.downloader.createDownload(image_url, {
filename: local_image_url // filename:下载任务在本地保存的文件路径
}, function(download, status) {
if(status != 200){
// 下载失败,删除本地临时文件
debug && console.log('下载失败,status'+status);
if(local_image_url != null){
plus.io.resolveLocalFileSystemURL(local_image_url, function(entry) {
entry.remove(function(entry) {
debug && console.log("临时文件删除成功" + local_image_url);
// 重新下载图片
download_img();
}, function(e) {
debug && console.log("临时文件删除失败" + local_image_url);
});
});
}
}else{
// 把下载成功的图片显示
// 将本地URL路径转换成平台绝对路径
obj.setAttribute('src', plus.io.convertLocalFileSystemURL(local_image_url));
obj.setAttribute('data-loaded', true);
obj.classList.add('img-lazyload');
callback && callback();
}
});
download_task.start();
}
download_img();
}
}