蔡繁荣
蔡繁荣
  • 发布:2015-07-01 14:41
  • 更新:2022-08-24 17:15
  • 阅读:26932

分享基于plus.downloader的图片懒加载功能,支持本地缓存v1.1.0

分类:MUI

今天试用了下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();  
    }  

}
52 关注 分享
BoredApe 粥冰 羊羽亻子 Loadingz hilongjw wenju Nation LFZ 豆花饭 豆腐果lyl DCloud_UNI_CHB 后海 G_jia DCDDD 老贪嗔痴 lauhome ztingjian 球风无痕 王帆 信不过你开车 建东 EM b***@msn.com 5675557 l***@boholo.com chenyumu 地球人 小白免 4***@qq.com 老火 成都H5 牛顿爱吃苹果 陨落星辰 jwenlee shwanYu 1***@qq.com WinXP qiuxiaojun ROBOT10086 3***@qq.com 5***@qq.com 1***@qq.com [已删除] android_yang 全栈开发南京 杨婆婆管家家 n***@qq.com 7***@qq.com 邱水仙 1***@qq.com

要回复文章请先登录注册

蔡繁荣

蔡繁荣 (作者)

回复 xdoctor :
具体你可以看下plus.io的相关API说明
2016-05-31 23:39
xdoctor

xdoctor

我有个疑问。
plus.downloader.createDownload()//这里的下载到的地址可以通过 download.filename获取
obj.setAttribute('src', plus.io.convertLocalFileSystemURL(local_image_url));//这是被下载元素的绝对路径
请问 这时到底被下载哪里了??1还是2
2016-05-31 22:18
a15965734368

a15965734368

后台一次次下载有点太耗费资源了,而且触发onload事件是异步的,同一时间保存10张图片会导致app发热,卡顿甚至卡死!需要继续优化下图片缓存到本地的机制,从异步改为同步,同步也有两种规则,是图片下载同步和保存到本地同步,或者是图片下载是异步的,保存到本地是同步的!其中许多需要各位大牛来讨论一下!
2016-05-07 15:54
a15965734368

a15965734368

回复 wenju :
用css3的animate
2016-05-07 11:01
蔡繁荣

蔡繁荣 (作者)

回复 5675557 :
哈哈,看到这么用心的评论,也是棒棒哒:)
2016-05-04 22:10
l***@boholo.com

l***@boholo.com

先收着
2016-05-04 14:56
5675557

5675557

灰常感谢!!!!特地登录来感谢LZ全小区~
我照着官网的Demo写完..不知道为啥图片都显示不了,只有先下拉 再滑下来 图片才能显示..可能是哪里的样式冲突了...
然后怒摔键盘....
然后看到了LZ的文章...
然后~捡起键盘吹吹~照着LZ的文章写了一遍 现在实现了 效果棒棒哒!!!!!!
2016-05-03 17:22
肥陈

肥陈

回复 蔡繁荣 :
谢谢 谢谢 粗心了
2016-05-03 09:04
蔡繁荣

蔡繁荣 (作者)

回复 肥陈 :
最底部有md5.js文件附件链接
2016-04-27 23:44
肥陈

肥陈

md5 is not defined 为什么
2016-04-26 11:45